1、正则表达式是用字符串描述的一个匹配规则,使用正则表达式可以快速判断给定的字符串是否符合匹配规则。Java标准库java.util.regex内建了正则表达式引擎
2、Java字符串用\\表示\,比如要判断用户输入的年份是否是20##年,对应的正则表达式就是:20\d\d,java中是20\\d\\d
3、利用string.matches()进行匹配判断,如"2019".matches("20\\d\\d") true;
匹配规则
1、匹配任意字符:可以匹配一个字符且仅限一个字符,比如a.c可以匹配abc a&c acc
2、匹配数字:\d 比如00\d可以匹配004 005
匹配非数字:\D匹配一个非数字
3、匹配常用字符串:用\w可以匹配一个字母、数字或下划线
\W匹配\w不能匹配的
4、匹配空格:用\s可以匹配一个空格字符,注意空格字符不但包括空格,还包括tab字符(在Java中用\t表示)
\S匹配\s不能匹配的
重复匹配
1、\d匹配一个数字,\d*匹配多个数字。修饰符*可以匹配任意个字符,包括0个字符
2、修饰符+可以匹配至少一个字符
3、修饰符?可以匹配0个或一个字符
4、修饰符{n}可以精确匹配n个字符
5、修饰符{n,m}可以匹配n~m个字符
复杂匹配规则
1、匹配开头和结尾
用正则表达式进行多行匹配时,我们用^表示开头,$表示结尾。例如,^A\d{3}$,可以匹配"A001"、"A380"
2、匹配指定范围
使用[...]可以匹配范围内的字符,例如,[123456789]可以匹配1~9,这样就可以写出上述电话号码的规则:[123456789]\d{6,7}
把所有字符全列出来太麻烦,[...]还有一种写法,直接写[1-9]就可以
还有一种排除法,即不包含指定范围的字符。假设我们要匹配任意字符,但不包括数字,可以写[^1-9]{3}
3、或规则匹配
用|连接的两个正则规则是或规则,例如,AB|CD表示可以匹配AB或CD
分组匹配
1、对于\d{3,4}\-\d{6,8}进行匹配时候,要利用()进行分组,变成(\d{3,4})\-(\d{6,8})
现在没办法利用String.matches()进行简单判断,必须引用java.util.regex包,用Pattern对象匹配,匹配后获得一个Matcher对象,如果匹配成功,直接从Matcher.group(index)返回子串。
Pattern p = Pattern.compile("(\d{3,4})\-(\d{6,8})");
Matcher m = p.matcher("010-12345678");
if(m.matches()){
String s1=m.group(1); 010
String s2=m.group(2); 12345678
String s=m.group(0); 010-12345678
}
我们在前面的代码中用到的正则表达式代码是String.matches()方法,而我们在分组提取的代码中用的是java.util.regex包里面的Pattern类和Matcher类。实际上这两种代码本质上是一样的,
因为String.matches()方法内部调用的就是Pattern和Matcher类的方法。但是反复使用String.matches()对同一个正则表达式进行多次匹配效率较低,因为每次都会创建出一样的Pattern对象。
完全可以先创建出一个Pattern对象,然后反复使用,就可以实现编译一次,多次匹配
非贪婪匹配
1、正则表达式默认使用贪婪匹配:任何一个规则,它总是尽可能多地向后匹配,因此,\d+总是会把后面的0包含进来。
要让\d+尽量少匹配,让0*尽量多匹配,我们就必须让\d+使用非贪婪匹配。在规则\d+后面加个?即可表示非贪婪匹配
我们再来看这个正则表达式(\d??)(9*),注意\d?表示匹配0个或1个数字,后面第二个?表示非贪婪匹配,因此,给定字符串"9999",
匹配到的两个子串分别是""和"9999",因为对于\d?来说,可以匹配1个9,也可以匹配0个9,但是因为后面的?表示非贪婪匹配,
它就会尽可能少的匹配,结果是匹配了0个9。
正则表达式匹配默认使用贪婪匹配,可以使用?表示对某一规则进行非贪婪匹配
搜素和替换
1、分割字符串
String.split()方法传入的正是正则表达式
"a, b ;; c".split("[\\,\\;\\s]+"); 结果// { "a", "b", "c" }
2、搜索字符串
Matcher.find()
String s = "the quick brown fox jumps over the lazy dog.";
Pattern p = Pattern.compile("\\wo\\w");
Matcher m = p.matcher(s);
while (m.find()) {
String sub = s.substring(m.start(), m.end()); substring()用于截取字符串,第一个参数是截取的初始位置,第二个参数是截取的末尾位置(可以没有)。
3、替换字符串
String.replaceAll() 它的第一个参数是正则表达式,第二个参数是待替换的字符串
String s = "The quick\t\t brown fox jumps over the lazy dog.";
String r = s.replaceAll("\\s+", " ");
System.out.println(r); // "The quick brown fox jumps over the lazy dog."
4、反向引用
如果我们要把搜索到的指定字符串按规则替换,比如前后各加一个<b>xxxx</b>,这个时候,使用replaceAll()的时候,我们传入的第二个参数可以使用$1、$2来反向引用匹配到的子串
String s = "the quick brown fox jumps over the lazy dog.";
String r = s.replaceAll("\\s([a-z]{4})\\s", " <b>$1</b> ");
结果:the quick brown fox jumps <b>over</b> the <b>lazy</b> dog