正则表达式简介
-
正则表达式用字符串来描述规则, 并用来匹配字符串
-
正则表达式有一套标准可以用于任何语言
-
java字符串用
\表示 -
java.util.regex内建了正则表达式引擎
匹配规则
- 匹配规则: 从左到右按规则匹配
- 正则表达式
abc, 只能精确匹配"abc". - 如果正则表达式有特殊字符, 需要用
进行转义,a&c匹配"a&c" - 正则表达式在java中也是一个字符串, 所以
a&c匹配a\&c, 也是Java字符串的转义字符, 两个\表示一个- 匹配中文, 使用ASCII字符.
u####
匹配任意字符
- 精确匹配意义不大, 直接用
String.equals()可以做到 .匹配任意一个字符, 且仅限一个字符
匹配数字
- 匹配
0~9数字:d进行匹配 d仅限单个字符- 各个名词含义区别:
d: 正则"\d": java中用来表示正则的字符串"abc": 字符串, 其实正则在java中也是字符串
匹配常用字符
w: 匹配一个字母, 数字, 下划线w: 不能匹配:#, 空格等
匹配空格字符
s匹配一个空格字符.- 还包括tab字符, (java中用
)表示
匹配非数字等
d匹配数字,D匹配非数字w匹配字符,W匹配w不能匹配的S匹配s不能匹配的
重复匹配
*: 匹配任意个字符, 就是好多个, 无限个+: 至少匹配一个字符?: 匹配一个或者0个{n}: 匹配n个{n,m}: 匹配n-m个
复杂匹配规则
匹配开头和结尾
^表示开头$表示结尾
匹配指定范围
[....]匹配指定范围内字符[^...]: 排除指定范围的字字符[1-9]: 表示1-9[0-9a-fA-F]: 表示大小不限制的十六进制
或规则匹配
|: 两个正则规任选一个
使用括号
(...): 公共部分提取出来, 括号里面表示子规则
// learn go
String re = "learn\s([jJ]ava|(p|P)hp|go)";
System.out.println("learn Java".matches(re));
System.out.println("learn php".matches(re));
System.out.println("go".matches(re));
分组匹配
- 使用
(...)对规则进行分组
String reg = "(\d{3,4})-(\d{7,8})";
Pattern p = Pattern.compile(reg);
Matcher m = p.matcher("010-1234551");
if (m.matches()) {
System.out.println(m.group(1));
System.out.println(m.group(2));
} else {
// 匹配失败
}
Pattern
String.matches()调用的是Pattern和Matcher- 反复调用效率低
- 先创建
Pattern, 然后反复使用, 编译一次, 多次匹配 group(0): 表示匹配整个字符串- 使用Matcher时, 必须首先调用
matches()判断是否匹配成功.
非贪婪匹配
-
正则表达式使用贪婪模式, 尽可能多的向后匹配
-
?表示非贪婪模式 -
?的含义:d?? -
举个例子:
(d??)(9*), 匹配299999: 结果->""和"99999 -
因为
d?可以匹配1个9, 或者0个. 变成非贪婪模式, 就匹配0个.
搜索和替换
分割字符串
- 使用正则表达式分割字符串
String.split()方法传入正则表达式.
搜索字符串
* 获取到Matcher对象之后, 反复调用find()方法.
替换字符串
String.replaceAll(), 第一个参数是正则表达式, 第二个参数是待替换的字符串
反向指引
replaceAll(): 第二个参数中, 可以使用$1, $2代替, 前面的匹配到的模板
总结
Matcher m = pattern.matcher(template);
StringBuilder sb = new StringBuilder();
while (m.find()) {
String key = m.group(m.groupCount());
String value = data.get(key).toString();
m.appendReplacement(sb, value);
}
m.appendTail(sb);
return sb.toString();
appendReplacement和appendTail的神奇配合用法, 最后还是不理解这样可以成功的原因