1、前言

之前在学习Python时,我已经说过正则表达式的相关语法,这里不再赘述了

现在开始学习Java中的正则表达式匹配。

需要注意的是Java中用\\代表\,Python中的\d在Java中写为\\d

2、模块:java.util.regex.*

3、用法

3.1、预编译正则字符串:Pattern.compile( regrex_string )

Pattern p = Pattern.compile( regrex_string

3.2、用Pattern匹配目标字符串:matcher()

Matcher m = p.matcher( Obj_String;

3.3、分组提取:group()

String s = m.group( n );//提取匹配到的第n项 

n取0时是整个字符串;取1时是第一个子串;取2时是第二个子串...

注意

分组提取之前,必须首先调用matches()判断是否匹配成功,成功后才能调用group()提取子串。

完整例子

import java.util.regex.*;

public class Main {
    public static void main(String[] args)  {
        Pattern p = Pattern.compile("(\\d{3,4})\\-(\\d{7,8})");
        Matcher m = p.matcher("010-12345678");
        if(m.matches()){
            String g1 = m.group(1);
            String g2 = m.group(2);
            System.out.println(g1);
            System.out.println(g2);
        }
        else{
            System.out.println("匹配失败");
        }
    }
}

4、非贪婪匹配:末尾补?,尽量少匹配

正则表达式默认使用贪婪匹配:任意规则,它总是尽可能多地向后匹配。

比如,一串数字123000以若干个0结尾,要分别提取数字和0,那么很多人都会认为正则字符串应当写为"(\\d+)(0*)"。但是提取的结果是"123000"和"",就是由于贪婪匹配造成的。

要让\d+少匹配,0*多匹配,我们就要让\d+使用非贪婪匹配,在之后添加?写为\d+?即可实现。

区分?的含义

\d??,第一个?表示0或1个数字,加上第二个?表示非贪婪匹配,尽量少匹配,所以实际上匹配0个数字。

5、方法

5.1、分割字符串:String.split( regex_string )

String的split()方法支持用正则表达式分割字符串。

5.2、搜索:matcher.find()

我们获取到Matcher对象后,调用find()方法,返回的是符合匹配规则的子串。

不断调用find()就能得到所有符合规则的子串了。

5.3、替换字符串:s.replaceAll( regex , Obj_String )

把String s中的所有符合regex的子串替换为Obj_String。

5.4、反向引用:$1、$2、$3....

替换时,如果想用某个特定字符串指代查找到的子串,可以用$1、$2...代指,比如,给查找到的字符串前后加<b>和</b>,那么在replaceAll时,传入的第二个参数(也就是替换成的新串)可以写成<b>$1</b>。

例子:给String中的所有四字子串前后加上<b>与</b>

String s = "the quick brown fox jumps over the lazy dog.";
String r = s.replaceAll("\\s([a-z]{4})\\s", " <b>$1</b> ");
//r = the quick brown fox jumps <b>over</b> the <b>lazy</b> dog.

本例中,就是用$1代指了查找到的子串。