文章目录
正则表达式
- 正则表达式是对字符串执行模式匹配的技术
- 正则表达式:
regular expression
,简称:RegExp
正则的基本使用
String connent = "...";//需要进行匹配的字符串
String regexp = "\\d\\d\\d\\d";//正则表达式,表示四个连续数字
Pattern pattern = Pattern.complie(regexp);//创建正则表达式模式对象
Matcher matcher = pattern.matcher(connect);//创建对应的匹配器
while(matcher.find()){
//若匹配器定位到一个匹配的子字符串就会返回true
System.out.println(matcher.group(0));
}
Pattern与Matcher底层原理
String regexp = "(\\d\\d)(\\d\\d)";
//什么是分组:比如 (\d\d)(\d\d) ,正则表达式中有()表示分组,第1个()表示第1组,第2个()表示第2组...
Pattern pattern = Pattern.complie(regexp);/
Matcher matcher = pattern.matcher(connect);
while(matcher.find()){
System.out.println(matcher.group(0));
}
matcher.find()完成的任务 (考虑分组):
- 根据指定的规则 ,定位满足规则的子字符串
- 将匹配子字符串的索引记录到 matcher对象的属性
int[] groups
- 开始索引存入
groups[0]
, 结束索引+1后存入groups[1]
- 记录匹配子字符串的第一组:开始索引存入
groups[2]
,结束索引+1后存入groups[3]
- 记录匹配子字符串的第二组:开始索引存入
groups[4]
,结束索引+1后存入groups[5]
- 后续第N组以此类推
- 同时记录matcher对象的属性
oldLast
的值为匹配子字符串的结束索引+1的值。即下次执行find()时,就从oldLast开始匹配
public String group(int group) {
if (first < 0)
throw new IllegalStateException("No match found");
if (group < 0 || group > groupCount())
throw new IndexOutOfBoundsException("No group " + group);
if ((groups[group*2] == -1) || (groups[group*2+1] == -1)) return null;
return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
}
//根据 groups[group*2] 和 groups[group*2+1] 记录的位置,从content开始截取子字符串返回
正则表达式语法
- 限定符
- 选择匹配符
- 分组组合和反向引用符
- 特殊字符
- 字符匹配符
- 定位符
元字符-转义符
- 使用正则表达式检索特殊字符,需用到转义符
\\
- 需转义的特殊字符:
* + ( ) $ / \ ? [ ] ^ { } .
java
中的\\
,等同于其他语言的\
元字符-字符匹配符
[]
可接受的字符列表,如[abc]
表示a、b、c
中任意单个字符,该符号中的特殊符号都视为单个参与匹配其本身的字符[^]
不接受的字符列表,如[^ab]
表示除a、b
以外的任意单个字符(包括数字和特殊字符)-
连字符,如a-z
表示a到z的任意单个字符.
匹配除\n
以外任意单个字符,如需匹配.
还需使用\\.
\\d
匹配单个数字字符,等同于[0-9]
\\D
匹配单个非数字字符,等同于[^0-9]
\\w
匹配单个数字、大小写字母字符、下划线,等同于[0-9a-zA-Z_]
\\W
匹配单个非数字、大小写字母字符、下划线,等同于[^0-9a-zA-Z_]
\\s
匹配任意单个空白字符(空格、制表符)\\S
匹配任意单个非空白字符(?i)
不区分大小写,(?i)abc
都不区分大小写,a(?i)bc
后面两位不区分大小写,a((?i)b)c
中间一位字符不区分大小写- 使匹配模式不区分大小写:
Pattern pattern = Pattern.compile(regexp,Pattern.Case.INSENSITIVE)
元字符-选择匹配符
- 选择匹配符
|
,匹配该符号前或后的表达式例如:
ab|cd
,匹配ab、ac
- 匹配符
&&
,匹配同满足该符号前后的表达式例如:
[a-z&&[abc]]
,匹配a、b、c
元字符-限定符
*
前面字符和组合项重复0或n次+
前面字符和组合项重复1或n次?
前面字符和组合项重复0或1次{n}
前面字符和组合项使用n次{n,}
前面字符和组合项使用至少n次{n,m}
前面字符和组合项使用最少n次,最多m次
元字符-定位符
^
指定起始字符$
指定结束字符\\b
匹配目标字符串的边界\\B
匹配目标字符串的非边界
正则-分组
(pattern)
非命名分组,捕获匹配字符串的子串,从1开始根据括号顺序自动编号(0为整个正则表达式模式匹配的字符串)(?<name>pattern)
命名分组,捕获匹配字符串的子串到编号或者名称中,name的字符串不能包含任何标点符号,不能以数字开头,可用(?'name')
形式替代尖括号
String regexp = "(?<g1>\\d\\d)(?<g2>\\d\\d)";//命名分组
Pattern pattern = Pattern.complie(regexp);/
Matcher matcher = pattern.matcher(connect);
while(matcher.find()){
System.out.println(matcher.group("g1"));
System.out.println(matcher.group("g2"));
}
特别分组:
(?:pattern)
不捕获匹配字符串的子串,用做|
组合模式部件,如:
hobb(?:y|ies)
更便捷于hobby|hobbies
(?=pattern
不捕获匹配字符串的子串,用于筛选匹配的字符串,如:
Window(?=95|2000)
只匹配Windows95、Window2000
的Window
(?!pattern)
不捕获匹配字符串的子串,用于选出不匹配的字符串,如:
Window(?!95|2000)
只匹配非Window95、Window2000
的Window
正则表达式常用类
- Pattern,正则表达式对象,该类无公共构造方法,通过调用其compile()静态方法获得Pattern对象,该方法接受一个正则表达式字符串作为第一个参数
- Matcher,对输入字符串进行解释和匹配的引擎,通过调用Pattern对象的matcher方法来获取Matcher实例对象
- PatternSyntaxException,非强制异常类,表示一个正则表达式模式语法错误
Pattern常用方法:
Pattern.matches(regexp,connent)
,整体匹配,判断匹配的字符串是否就是整体的字符串
Matcher常用方法:
反向引用
分组:用
()
组成一个比较复杂的匹配模式,一个()
中的部分可以视为一个子表达式或分组
捕获:将正则表达式中的子表达式/分组匹配的内容,保存到以数字命名或显式命名的组中。从左向右第一个分组组号为1,第二个为2,以此类推。0表示整个正则表达式匹配的内容
反向引用:
()
中的内容被捕获后,可以在其()
后被使用,从而写出一个实用的匹配模式。该引用可以用在正则表达式内部,也可用在表达式外部。内部反向引用\\分组号
,外部反向引用$分组号
//内部引用
String regexp = "(.)\\1+";
//表示第一分组匹配的子串用作匹配模式
//外部引用
String connent = "111222333";
Pattern pattern = Pattern.complie(regexp);
Matcher matcher = pattern.matcher(connent);
System.out.println(matcher.replaceAll("$1"));
//输入123,替换为每次匹配的字符第一分组
String类中的正则
String connent = "JDK1.3、JDK1.4";
String connent_1 = connent.replaceAll("JDK1\\.(?:3|4)","JDK");
//connent_1输出JDK、JDK
String phone = "1388889999";
boolean isOk = phone.matches("1(38|39)\\d{8}");
//isOk输出true
String connent = "Hello,world!jack";
String[] arr = connent.spilt(",|!");
//arr[0],arr[1],arr[2]分别为Hello、world、jack