11 正则表达式

    符合一定规则的表达式。

1、作用

    用于专门操作字符串。

    String中提供了matches(String regex)方法,用于通知此字符串是否匹配给定的正则表达式。

2、特点

    用一些特定的符号,来表示一些代码操作,这样就简化了书写。

3、好处

    可以简化对字符串的复杂操作。

4、弊端

    符号定义越多,正则表达式越长,阅读性越差。

5、对QQ号码进行校验,5-15位,只能是数字。


public class QQ {

    public static void main(String[] args) {

        String qq="81276490";
        String regex = "[1-9][0-9]{4,14}";
        boolean b = qq.matches(regex);
        
        if (b) {
            System.out.println("正确");
        }else {
            System.out.println("错误");
        }
    }
}
其中:

[1-9]表示只能取1到9之间的数。

[0-9]表示只能取0到9之间的数。

{4,14}表示最少重复4次,最多重复14次。


11.1 正则表达式规则(只列出了一些常用的)


1、字符类
[abc]abc(简单类)
[^abc]任何字符,除了 abc(否定)
[a-zA-Z]azAZ,两头的字母包括在内(范围)

例如:  String s = "a";
            String regex = "[a,b,c]";
            boolean b = s.matches(regex);
            System.out.println(b);


2、预定义字符类
.任何字符(与行结束符可能匹配也可能不匹配)
\d数字:[0-9]
\D非数字: [^0-9]
\s空白字符:[ \t\n\x0B\f\r]
\S非空白字符:[^\s]
\w单词字符:[a-zA-Z_0-9]
\W非单词字符:[^\w]

例如:String s = "a9";
          String regex = "[a-zA-Z]\\d";
          boolean b = s.matches(regex);
          System.out.println(b);


3、边界匹配器
^行的开头
$行的结尾
\b单词边界
\B非单词边界


4、Greedy 数量词
X?X,一次或一次也没有
X*X,零次或多次
X+X,一次或多次
X{n}X,恰好 n
X{n,}X,至少 n
X{n,m}X,至少 n 次,但是不超过 m

例子:字母后面的数字出现0次或多次。

        String s = "a98";
        String regex = "[a-zA-Z]\\d*";
        boolean b = s.matches(regex);
        System.out.println(b);


5、Logical 运算符
XYX 后跟 Y
X|YXY
(X)X,作为捕获组


6、匹配手机号:13...,15...,18...

    public static void checkTel(){
        String s = "13812930477";
        String regex = "1[358]\\d{9}";
        boolean b = s.matches(regex);
        System.out.println(b);
    }


11.2 正则表达式切割字符串

1、用空格切割字符串,空格出现的次数不确定。


public class SplitDemo {

    public static void main(String[] args) {

        splitDemo();
    }
    
    public static void splitDemo(){
        
        String s = "zhangsan  lisi      wangwu";
        String regex = " +";
        String[] arr = s.split(regex);
        System.out.println(arr.length);
        
        for (String string : arr) {
            System.out.println(string);
        }
    }
}

2、用.来切割字符串

    public static void splitDemo(){
        
        String s = "zhangsan.lisi.wangwu";
        String regex = ".";
        String[] arr = s.split(regex);
        System.out.println(arr.length);
        
        for (String string : arr) {
            System.out.println(string);
        }
    }

输出结果数组长度为0。

因为"."在正则表达式中是特殊符号,所以需要时要转义一下"\\."


3、用叠词来切割字符串

    public static void splitDemo(){
        
        String s = "aczzukksiyyyhiiiiiok";
        String regex = "(.)\\1+";
        String[] arr = s.split(regex);
        System.out.println(arr.length);
        
        for (String string : arr) {
            System.out.println(string);
        }
    }

    为了可以让规则的结果被重用,可以将规则封装成一个组,用()完成。组都有编号,从1开始。想要使用已有的组可以通过\编号的形式来获取。


11.3 正则表达式替换字符串

        用到了String的replaceFirst(String regex, String replacement)方法。

1、将字符串中的数字出现4次或以上时替换成*。例如dada23325435f123dsf88943der3442


public class replaceAllDemo {

    public static void main(String[] args) {

        String s = "dada23325435f123dsf88943der3442";
        String regex = "\\d{4,}";
        replaceAllDemo(s, regex, "*");
    }

    public static void replaceAllDemo(String str,String regex,String newStr){
        
        str = str.replaceAll(regex, newStr);
        System.out.println(str);
    }
}

结果:dada*f123dsf*der*


2、将字符串中的叠词替换成#。例如aczzukksiyyyhiiiiiok


public class replaceAllDemo {

    public static void main(String[] args) {

        String s = "aczzukksiyyyhiiiiiok";
        String regex = "(.)\\1+";
        replaceAllDemo(s, regex, "#");
    }

    public static void replaceAllDemo(String str,String regex,String newStr){
        
        str = str.replaceAll(regex, newStr);
        System.out.println(str);
    }
}

结果:ac#u#si#h#ok


3、将字符串中的叠词替换成一个。


public class replaceAllDemo {

    public static void main(String[] args) {
      
        String s = "aczzukksiyyyhiiiiiok";
        String regex = "(.)\\1+";
        replaceAllDemo(s, regex, "$1");
    }

    public static void replaceAllDemo(String str,String regex,String newStr){
        
        str = str.replaceAll(regex, newStr);
        System.out.println(str);
    }
}

结果:aczuksiyhiok


11.4 正则表达式获取子串


1、操作步骤

  • 将正则表达式封装成对象Pattern

  • 让正则表达式对象和要操作的字符串相关联

  • 关联后,获取正则匹配引擎

  • 通过引擎对符合规则的子串进行操作


2、从字符串中截取连续3个字符的子串

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SubStringDemo {

    public static void main(String[] args) {

        subStringDemo();
    }

    public static void subStringDemo(){
        
        String s = "hei ma wo lai le,yi ying yao hao hao xue xi";
        String regex = "\\b[a-z]{3}\\b";
        
        //将正则表达式封装成对象
        Pattern p = Pattern.compile(regex);
        //正则和要操作的字符串相关联
        Matcher m = p.matcher(s);
        //将规则作用到字符串上,并进行符合规则的子串查找
        while (m.find()) {
            System.out.println(m.group());
            
        }
    }
}


11.5 网页爬虫

1、 获取指定网页中的邮件地址


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class SubStringDemo {

    public static void main(String[] args) throws IOException {

        getMails();
    }
    
    public static void getMails() throws IOException{
        URL url = new URL("http://192.168.1.11:8080/myweb/text.html");
        URLConnection conn = url.openConnection();
        BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        
        String line = null;
        String mailReg = "\\w+@\\w+(\\.\\w+)+";
        
        //将正则表达式封装成对象
        Pattern p = Pattern.compile(mailReg);
        
        while (null!=(line=br.readLine())) {
            
            //正则和要操作的字符串相关联
            Matcher m = p.matcher(line);
            
            //将规则作用到字符串上,并进行符合规则的子串查找
            while (m.find()) {
                System.out.println(m.group());
            }
            
        }
        
        br.close();
    }
}