Pattern,Matcher
正则表达式
正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串
Pattern类
Pattern类表示一个正则表达式对象,Pattern类没有公共的构造方法,要创建一个Pattern对象,调用其公共的静态方法,返回一个Pattern对象
1 |
|
public static boolean matches(String regex, CharSequence input)
编译给定正则表达式并尝试将给定输入与其匹配。
上面的使用太繁琐,一般使用场景我们只需要匹配检查一次即可,所以可以省略为如下方式:
1 |
|
String类的matches方法
另外正则运用在字符串上,上面那样普通使用还是麻烦,因此在字符串对象里提供快速调用的方法(matches/split/replace)
1 |
|
String的matches和Pattern的matches的源码如下,可以发现其实内部还是用了第一种方式
1 |
|
1 |
|
匹配
特殊字符
注意:在java中,需要 “ \ “的匹配符,需要用”\“ 进行转义
java匹配默认贪婪匹配,尽量可能匹配多的
Matcher类
public bollean find(int start) 返回目标字符串中是否包含与 Pattern 匹配的子串
public String group(int group) 返回上一次与 Pattern 匹配的子串
public int start(int group) 返回上一次与 Pattern 匹配的子串在目标字符串中的开始位置
public int end(int group) 返回上一次与 Pattern 匹配的子串在目标字符串中的结束位置加 1
public boolean lookingAt() 返回目标字符串前面部分与 Pattern 是否匹配,与 matches 方法类似,此方法始终从区域的开头开始
public boolean matches() 返回整个目标字符串与 Pattern 是否匹配
public Matcher reset() 将现有的 Matcher 对象应用于一个新的字符序列。
public boolean find()
尝试查找与该模式匹配的输入序列的下一个子序列。根据指定规则,定位满足规则的子字符串,找到后将子字符串的开始索引记录到matcher对象属性int[] groups
把匹配字符串的开始索引放到group[0],结束索引值+1记录到groups[1],返回[groups[0] , groups[1])的字符串
同时记录oldlast的值为子字符串结束的索引+1,即下次执行find时,就从group[1]开始匹配找下一个满足的子字符串
分组
可以简单理解为, 把匹配的规则当成一个变量来使用 ,组的概念大部分也是通用的,用”()” 即定义了一个匹配组,捕获组可以通过从左到右计算其开括号来编号
例如,在表达式regex中 ((A)(B(C)))中,存在三个这样的组:(A) (B(C)) (C)
整个表达式((A)(B(C))) 放在groups[0],groups[1],第一个组(A)放在groups[2],groups[3],第二个组(B(C)) 放在groups[4],groups[5],以此类推
编号为0的组代表整个表达式,可以理解为, 组的号码是从1开始,并且从左到右增加
public String group(int group)源码
1 |
|
找长度为4的数字
1 |
|
命名分组
分组默认为无命名分组
(?< name >) 可以给分组命名,通过Mathcer.group(“name”)输出分组内容
非捕获分组
分组不怕捕获,不能使用Mather.group()
非贪婪匹配
java默认使用贪婪匹配
如果要使用非贪婪匹配,可以在其他限定符 (*,+,?,{n},{n,},{n.m})之后再加一个”?”,非贪婪模式匹配到的是尽可能短的字符串
1 |
|
反向引用
圆括号内容被捕获后,可以在这个括号后被使用,从而写出一个比较实用的匹配模式,称为反向引用,这种引用可以在正则表达式内部,也可以在正则表达式外部,内部使用\分组号,外部使用**$分组号**
匹配两个连续相同的数字:(\d)\1
匹配五个连续相同的数字:(\d)\1{4}
匹配4位回文数,如5225,1551:(\d)(\d)\2\1
切割
根据重复的字符进行切割,例如: “abctttttttcdemmmmmmfglllllll——-“ 切割结果为 [abc,cde,fg], 这里就需要反向引用,要使用到组,反向引用方式: \1或者$1。
组的另外说明:在regex里用\1引用,不在regex用$1引用
如: String[] strs = name.split(“(.)\1+”)和String result = name.replaceAll(“(\d{3})”, “$1”)
1 |
|
替换
String中的替换方法
public String replace(CharSequence target, CharSequence replacement) 替换单个字符,不使用到正则
public String replaceAll(String regex, String replacement) 替换字符串,使用到正则
public String replaceFirst(String regex, String replacement) 替换匹配的第一个字符串,使用到正则
Matcher中的替换方法
public String replaceAll(String replacement)
要将上面的重复字符替换为单个字符,即结果为 abctcdemfgl-
1 |
|
把手机号码的中间思维替换为 ****, 做法类似
方法1:分成三组
1 |
|
方法2:分成两组
1 |
|