JAVA基础学习day26--正则表达式

12/12/2015来源:Java教程人气:1616

一、正则表达式

1.1、概述

符合一规则的表达式:用于专门操作字符串。

正则表达式则必须依靠Pattern类与Matcher类,这两个类都在java.util.regex包中定义。Pattern类的主要作用是进行正则规范的编写,而Matcher类主要是执行规范,验证一个字符串是否符合其规范。

Pattern:

正则表达式的编译表示形式。

指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建 Matcher 对象,依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。

因此,典型的调用顺序是

 Pattern p = Pattern.compile("a*b");
 Matcher m = p.matcher("aaaaab");
 boolean b = m.matches();

 

Matcher:

通过解释 Patterncharacter sequence 执行匹配操作的引擎。

通过调用模式的 matcher 方法从模式创建匹配器。创建匹配器后,可以使用它执行三种不同的匹配操作:

  • matches 方法尝试将整个输入序列与该模式匹配。

  • lookingAt 尝试将输入序列从头开始与该模式匹配。

  • find 方法扫描输入序列以查找与该模式匹配的下一个子序列。

每个方法都返回一个表示成功或失败的布尔值。通过查询匹配器的状态可以获取关于成功匹配的更多信息。 

二、正则规则-预定义字符类

2.1、规则-预定义字符类

常用正则规则

 
No.
规范
描述
No.
规范
描述
1
\\
表示反斜线(\)字符
2
\t
表示制表符
3
\n
表示换行
4
[abc]
字符a、b或c
5
[^abc]
除了a、b、c之外的任意字符
6
[a-zA-Z0-9]
表示由字母、数字组成
7
\d
表示数字0-9
8
\D
表示非数字[^0-9]
9
\w
表示字母、数字、下划线
10
\W
表示非字母、数字、下划线[^\w]
11
\s
表示所有空白字符(换行、空格等)
12
\S
表示所有非空白字符[^\s]
13
^
行的开头
14
$
行的结尾
15
.
匹配除换行符之外的任意字符

 

 

 

 

 

2.2、匹配规则

 

    数量表示(X表示一组规范)
 
No.
规范
描述
No.
规范
描述
1
X
必须出现一次
2
X?
可以出现0次或1次
3
X*
可以出现0次、1次或多次
4
X+
可以出现1次或多次
5
X{n}
必须出现n次
6
X{n,}
必须出现n次以上
7
X{n,m}
必须出现n~m次

 

 

 

 

 
逻辑运算符(X、Y表示一组规范)
 
No.
规范
描述
No.
规范
描述
1
XY
X规范后跟着Y规范
2
X | Y
X规范或Y规范
3
(X)
做为一个捕获组规范

 

 

 

 

 
2.3、Pattern类的常用方法
No.
方法
类型
描述
1
public static Pattern compile(String regex)
普通
指定正则表达式规则
2
public Matcher matcher(CharSequence input)
普通
返回Matcher类实例
3
public String[] split(CharSequence input)
普通
字符串拆分
在Pattern类中如果要想取得Pattern类实例,则必须调用compile()方法。
2.4、Pattern常用方法
方法摘要
static Pattern compile(String regex)
          将给定的正则表达式编译到模式中。
static Pattern compile(String regex, int flags)
          将给定的正则表达式编译到具有给定标志的模式中。
 int flags()
          返回此模式的匹配标志。
 Matcher matcher(CharSequence input)
          创建匹配给定输入与此模式的匹配器。
static boolean matches(String regex, CharSequence input)
          编译给定正则表达式并尝试将给定输入与其匹配。
 String pattern()
          返回在其中编译过此模式的正则表达式。
static String quote(String s)
          返回指定 String 的字面值模式 String
 String[] split(CharSequence input)
          围绕此模式的匹配拆分给定输入序列。
 String[] split(CharSequence input, int limit)
          围绕此模式的匹配拆分给定输入序列。
 String toString()
          返回此模式的字符串表示形式。
 

 2.5、边界匹配器

 

边界匹配器
^ 行的开头
$ 行的结尾
\b 单词边界
\B 非单词边界
\A 输入的开头
\G 上一个匹配的结尾
\Z 输入的结尾,仅用于最后的结束符(如果有的话)
\z 输入的结尾

 

 

三、String对正则表达式的支持

 

3.1、常用方法

 

Matcher类的常用方法在
No.
方法
类型
描述
1
public boolean matches(String regex)
普通
字符串匹配
2
public String replaceAll(String regex,String replacement)
普通
字符串替换
3
public String[] split(String regex)
普通
字符串拆分

 

四、示例

4.1、验证用户输入不是QQ

 

/*
验证用户输入不是QQ号
QQ号以1-9开头,5-15位长度
都是数字使用\d或者[0-9]表示数字完成

*/
import java.util.*;
import java.util.regex.*;
class  RegexDemo1
{
    public static void main(String[] args) 
    {    
        //声明一个扫描器的变量,来接收用户键盘输入
        Scanner input=new Scanner(System.in);
        //接收输入数据
        String qq=input.nextLine();
        //调用校验
        checkQQ(qq);
    }

    /*
    校验QQ
    */
    public static void checkQQ(String qq)
    {
        //定义正则
        //String regex="^[1-9]\\d{4,14}$";
        String regex="[1-9][0-9]{4,14}";
        //获取Pattern对象
        Pattern p=Pattern.compile(regex);
        //验证字符串内容是否符合正则
        Matcher m=p.matcher(qq);
        //判断
        if(m.matches())
        {
            System.out.PRintln(qq+"是合法的QQ!");
        } else
        {
        System.out.println(qq+"不是合法的QQ!");
        }
    }
}

 

 

 

 

4.2、验证手机号码是不是正确

 

/*
验证手机号码是不是正确
手机号1开头,都是数字,长度11位
*/
import java.util.regex.*;
import java.util.*;
class RegexDemo2 
{
    public static void main(String[] args) 
    {
        Scanner input=new Scanner(System.in);
        String mobile=input.nextLine();
        checkMobile(mobile);
    }
    public static void checkMobile(String mobile)
    {
        //String regex="1[0-9]{10}";
        String regex="^[1][0-9]{10}$";
        Pattern p=Pattern.compile(regex);
        Matcher m=p.matcher(mobile);
        if(m.find())
        {
            System.out.println(mobile+"是合法的手机号码!");
        }
        else
        {
            System.out.println(mobile+"不是合法的手机号码!");
        }
    }
}

 

4.3、验证用户输入邮箱是否合法

 

/*
验证用户输入邮箱是否合法
*/
import java.util.regex.*;
import java.util.*;
class RegexMail 
{
    public static void main(String[] args) 
    {
        Scanner input =new Scanner(System.in);

        String email=input.nextLine();
        checkMail(email);
    }
    public static void checkMail(String email)
    {
        //邮件正则
        String regex="\\w+@\\w+(\\.\\w+)+";
        //直接使用String类的方法来比较
        boolean flag=email.matches(regex);
        //输出结果
        System.out.println(email+"..."+flag);
    }
}

 

4.4、字符串匹配

 

/*
字符串匹配
*/
import java.util.regex.*;
class RegextDemo3 
{
    public static void main(String[] args) 
    {
        String str="aoob";
        String reg="ao?b";
        boolean b=str.matches(reg);//false ?表示不出现或者最多只能出现一次
        System.out.println(str+"......"+b);

        reg="ao+b";//o最少出现一次,可出现多次
        b=str.matches(reg);
        System.out.println(str+"......"+b);//true

        str="ab";
        reg="ao+b";//o必须最少出现一次,
        b=str.matches(reg);
        System.out.println(str+"......"+b);//false

        str="ab";
        reg="ao*b";//可以不出现也可以出现多次
        b=str.matches(reg);
        System.out.println(str+"......"+b);//true

        str="aooooooob";
        reg="ao{4,}b";//o最少出现4次,可以更多次
        b=str.matches(reg);
        System.out.println(str+"......"+b);//true

        reg="ao{4,6}b}";//o现象4-6次
        b=str.matches(reg);//o出现了7次
        System.out.println(str+"......"+b);//false
    }
}

 

 

4.5、字符串切割

 

/*
切割
*/
import java.util.regex.*;
class RegexDemo2 
{
    public static void main(String[] args) 
    {
        split_Fun();
        System.out.println("================");
        split_Fun2();
        System.out.println("================");
        split_Fun3();
        System.out.println("================");
        split_Fun4();
        System.out.println("================");
        split_Fun5();
        
    }
    /*
    按空格切割
    */
    public static void split_Fun()
    {
        String str="zhangsan  lisi      wangwu     zhaoliu";
        String reg="\\s+";//\s表示空白字符也可以" +"表示

        String [] arr=str.split(reg);
        //长度
        System.out.println("长度"+arr.length);
        for(String s:arr)
        {
            System.out.println(s);
        }

    }
    /*
    按一个元素多次重复出现切割
    */
    public static void split_Fun2()
    {
        String str="zhangsan.lisi..wangwu...zhaoliu";
        String reg="\\.+";

        String [] arr=str.split(reg);
        //长度
        System.out.println("长度"+arr.length);
        for(String s:arr)
        {
            System.out.println(s);
        }

    }
    /*
    双反斜杠\\\\
    */
    public static void split_Fun3()
    {
        String str="c:\\abc\\a.txt";
        String reg="\\\\+";

        String [] arr=str.split(reg);
        //长度
        System.out.println("长度"+arr.length);
        for(String s:arr)
        {
            System.out.println(s);
        }

    }
    /*
    按照叠词来切割
    为了可以让规则被重用可以将规则封装为一个组
    用()完成,组的出现都有编号
    从1开始,想要使用已经有的组可以通过\n的形式来获取
    n就是组的编号
    */
    public static void split_Fun4()
    {
        String str="erkktyqquioppdffyphhct";
        //按照叠词来切割
        String reg="(.)\\1";  //(.)表示组,\1捕获组,

        String [] arr=str.split(reg);
        //长度
        System.out.println("长度"+arr.length);
        for(String s:arr)
        {
            System.out.println(s);
        }

    }
    /*
    按重复元素切割
    */
    public static void split_Fun5()
    {
        String str="helloaaworkldbbbuiopccc";
        //按照叠词来切割
        String reg="(.)\\1+";  //(.)表示组,\1捕获组,

        String [] arr=str.split(reg);
        //长度
        System.out.println("长度"+arr.length);
        for(String s:arr)
        {
            System.out.println(s);
        }

    }
    
}

 

4.6、替换

 

/*
正则替换
*/
import java.util.regex.*;
class ReplaceAllDemo 
{
    public static void main(String[] args) 
    {    //字符串中的数字替换为#号
        String str="wer123ty343232uio23232f889..ffdsaf4324qq";
        String reg="\\d{4,}"; //4个以上的数字替换
        replaceAll_Fun(str,reg,"#");
        System.out.println("=================");
        String str1="erkktyqqquizzzzzzofffpeeenmcvvhss";
        //将叠替换为$号
        String reg1="(.)\\1+";
        replaceAll_Fun(str1,reg1,"\\$");
        System.out.println("=================");
        String str2="erkktyqqquizzzzzzofffpeeenmcvvhss";
        //将叠替换为单个字符
        String reg2="(.)\\1+";
        replaceAll_Fun(str2,reg2,"$1"); //使用$获取组的内容
    }
    public static void replaceAll_Fun(String str,String reg,String newStr)
    {
        //替换
        str=str.replaceAll(reg,newStr);
        System.out.println(str);
    }
}

 

4.7、获取

 

/*
获取:使用正则表达式
将字符串符合规则的子串取邮
1.将正则表达式封装成对象
2.让正则对象和要操作的字符串相关联
3.关联扣, 获取正则匹配引擎
4.通过引擎对象符合规则的子串操作,比如取出
*/
import java.util.regex.*;
class RegexDemo4 
{
    public static void main(String[] args) 
    {
    getDemo1();
    System.out.println("===============");
    }
    public static void getDemo1()
    {
        String str="ming tian jiu yao fang jia le , da jia. AWT HELLO";
        String reg="\\b[A-Za-z]{3}\\b"; //按3个字母组成的单词获取\b表示单词边界
        //将规则封装为对象
        Pattern p=Pattern.compile(reg);
        Matcher m=p.matcher(str);
        //尝试查找与该模式匹配的输入序列的下一个子序列
        while(m.find())
        {
            //获取获取的组
            System.out.println(m.group());//jiu  yao jia jia
            System.out.println(m.start()+"...."+m.end());
        }

    }
}

 

4.8、示例

 

/*
将下列字符串转成:学要学编程
"我我...我我...我要...要要...学学学...学学...编编编...编程..程.程程...程...程";

1.如果只想知道该字符是否符合规则--使用匹配
2.想要将已经有的字符串变成另一个字符串,替换
3.想要按照自定义方式,将字符串变成多个字符串,---切割-获取规则以外的字符串
4.想要拿到符合要求的字符串子串,----获取---获取符合规则的子串
*/
import java.util.*;
class RegexText 
{
    public static void main(String[] args) 
    {
        String str="我我...我我...我要...要要...学学学...学学...编编编...编程..程.程程...程...程";
        /*
        替换
        先将..去掉
        再将重复的内容变成单个内容
        */
        str=str.replaceAll("\\.+","");//将.替换为""空字符串
        System.out.println(str);
        str=str.replaceAll("(.)\\1+","$1");//使用组,替换
        System.out.println(str);
    }
}

 

 

4.9、替换,切割

 

/*
192.168.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30
还按照字符串自然顺序,只要让它们每一段都 是3位即可。
1.按照每一段需要的最多的0进行补齐,那么每一段就会至少保证3位
2.将每一段只保留3位。这位的所有的ip地址都每一段3位
*/
import java.util.*;
import java.util.regex.*;
class  RegexText2
{
    public static void main(String[] args) 
    {
        String ip="192.168.1.254 102.49.23.013 10.10.10.10 2.2.2.2 8.109.90.30";
        
        //为每一段数字前加2个0
        ip=ip.replaceAll("(\\d+)","00$1");
        System.out.println(ip);
        /*00192.00168.001.00254 00102.0049.0023.00013 0010.0010.0010.0010 002.002.002.002
            008.00109.0090.0030 */
            //再次替换
        ip=ip.replaceAll("0*(\\d{3})","$1");
        System.out.println(ip);
        //192.168.001.254 102.049.023.013 010.010.010.010 002.002.002.002 008.109.090.030
    
        //切割
        String [] arr=ip.split(" +");
        /*
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr));
        */
        //或者使用TreeSet
        TreeSet<String> ts=new TreeSet<String>();
        for(String s:arr)
        {
            ts.add(s);
        }
        //遍历Set集合
        for(String s:ts)
        {    //将前置0删除
            System.out.println(s.replaceAll("0*(\\d+)","$1"));
        }
        /*
        2.2.2.2
        8.109.90.30
        10.10.10.10
        102.49.23.13
        192.168.1.254
        */
    }
}

  

五、爬虫

5.1、示例

/*
爬虫1
从页面爬邮箱
*/
import java.io.*;
import java.util.regex.*;
import java.util.*;
import java.net.*;
class  RegexTest1
{
    public static void main(String[] args) throws Exception
    {
        
        List<String> list=getMail();
        for(String s:list)
        {
            System.out.println(s);
        }
    }
    public static List<String> getMail() throws Exception
    {    
        //从指定网址http://www.hao123.com/
        String uaddr="http://www.hao123.com/";
        //转换为URL对象
        URL url=new URL(uaddr);
        //获取URLConnection对象,并连接,再获取流
        //openStream(),就是openConnection().getInputStream()是个字节流
        //封装为字符缓冲流
        BufferedReader br=new BufferedReader(new InputStreamReader(url.openStream()));
        //邮箱正则
        String reg="\\w+@\\w+(\\.\\w+)+";
        //获取封装对象
        Pattern p=Pattern.compile(reg);
         List<String> list = new ArrayList<String>();
        //开始读取流
        String line=null;
        while ((line=br.readLine())!=null)
        {
            //获取正则校验对象
            Matcher m=p.matcher(line);
            //获取
            while (m.find())
            {
                //获取组,并添加
                list.add(m.group());
            }
        }
        br.close();
        //返回结果集
        return list;

    }
}

 示例

/*
网页爬虫(蜘蛛)
*/
import java.io.*;
import java.util.regex.*;
class  RegexTest3
{
    public static void main(String[] args) throws Exception
    {
        getMail();
    }
    public static void getMail() throws Exception 
    {
        BufferedReader br=new BufferedReader(new FileReader("d:\\mail.txt"));

        String mailReg="\\w+@\\w+(\\.\\w+)+";
        Pattern p=Pattern.compile(mailReg);
        String line=null;
        while ((line=br.readLine())!=null)
        {    
            Matcher m=p.matcher(line);
            while (m.find())
            {
                System.out.println(m.group());
            }
        }
    }
}
/*
fdsfadsafdsfdsfsdf> abc@sina.com<fdslfdsfdsf;dsjfsdjf
fdsfadsafdsfdsfsdf> fdsfads@sina.com<fdslfdsfdsf;dsjfsdjf
fdsfadsafdsfdsfsdf> fdsaf@qq.com<fdslfdsfdsf;dsjfsdjf
afdsaffadsfadfssafdsdfdsfsdf> abc@sina.com<fdslfdsfdsf;dsjfsdjf
ffdsfadsafdsffdsfsdf> abc@163.com<fdslfdsfdsf;dsjfsdjf
safdsfadsafdssffdsfsdf> abc@sina.com<fdslfdsfdsf;dsjfsdjf
dsfdsfadsafdsfdsfsdf> fdsafdsc@sina.com<fdslfdsfdsf;dsjfsdjf

fafdfdsfadsafdsfdsfsdf> weweq@sina.com<fdslfdsfdsf;dsjfsdjf
fdsa>abc@sina.com<fdslfdsfdsf;dsjfsdjf
fdsfadsafdsfdsfsdf> adsdsafdsc@sina.com<fdslfdsfdsf;dsjfsdjf
safdsfadsafdsfdsfsdf> abc@sina.com<fdslfdsfdsf;dsjfsdjf
dsafdfdsfadsafdsfdsfsdf> abc@sina.com;fdslfdsfdsf;dsjfsdjf
ffdsfdsfadsafdsfdsfsdf> abc@sina.com <fdslfdsfdsf;dsjfsdjf
dsdsasaffdsfadsafdsfdsfsdf> abc@sina.com <fdslfdsfdsf;dsjfsdjf
*/