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 运算符
XY X 后跟 Y
X|Y XY
(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();
    }
}