正则表达式匹配规则
对于正则表达式来说,它只能精确匹配字符串。
例如:正则表达式“abc",只能匹配”abc",不能匹配“ab","Abc","abcd"等其他字符串。
如果想匹配非ASCII字符,例如中文,那么就用\u####的十六进制表示,例如: a\u548cc匹配的是字符串"a和c",中文字符和的Unicode编码是548c。
基本规则
匹配任意字符
我们可以用 . 匹配一个任意字符。
例如,正则表达式a.c中间的点可以匹配任意一个字符,它可以匹配abc,a&c,acc等,但是不能匹配ac、a&&c,因为 . 匹配一个字符且仅限一个字符。
匹配数字
如果我们只想匹配0~9这样的数字,可以用\d匹配。
例如:00\d可以匹配 007, 008,但不能匹配00A,0077,因为\d仅限单个数字字符。
匹配常用字符
用\w可以匹配一个字母、数字或下划线,w的意思是word。
例如:java\w可以匹配,javac,java9,java_,它不能匹配java#,java ,因为\w不能匹配#、空格等字符。
匹配空格字符
用\s可以匹配一个空格字符,空格字符不但包括空格,还包括tab字符(在Java中用\t表示)。
例如:a\sc,可以匹配a c, 它不能匹配ac,abc等。
匹配非数字
用\d可以匹配一个数字,而\D则匹配一个非数字。
例如,00\D可以匹配,00A,00#,但不能匹配007,008等。
类似的,\W可以匹配\w不能匹配的字符,\S可以匹配\s不能匹配的字符,这正好是相反的。
重复匹配
修饰符*可以匹配任意个字符,包括0个字符。
修饰符+可以匹配至少一个字符。
修饰符?可以匹配0个或一个字符。
如果想精确指定n个字符,用{n}就可以。
如果想指定n~m个字符,用{n,m}就可以。
单个字符的匹配规则如下:
正则表达式 | 规则 | 可以匹配 |
---|---|---|
A | 指定字符 | A |
\u548c | 指定Unicode字符 | 和 |
. | 任意字符 | a ,b ,& ,0 |
\d | 数字0~9 | 0 ~9 |
\w | 大小写字母,数字和下划线 | a ~z ,A ~Z ,0 ~9 ,_ |
\s | 空格、Tab键 | 空格,Tab |
\D | 非数字 | a ,A ,& ,_ ,…… |
\W | 非\w | & ,@ ,中 ,…… |
\S | 非\s | a ,A ,& ,_ ,…… |
多个字符的匹配规则如下:
正则表达式 | 规则 | 可以匹配 |
---|---|---|
A* | 任意个数字符 | 空,A ,AA ,AAA ,…… |
A+ | 至少1个字符 | A ,AA ,AAA ,…… |
A? | 0个或1个字符 | 空,A |
A{3} | 指定个数字符 | AAA |
A{2,3} | 指定范围个数字符 | AA ,AAA |
A{2,} | 至少n个字符 | AA ,AAA ,AAAA ,…… |
A{0,3} | 最多n个字符 | 空,A ,AA ,AAA |
复杂规则
匹配开头和结尾
用正则表达式进行多行匹配时,用^表示开头,$表示结尾。
匹配指定范围
使用[...]可以匹配指定范围内的字符,例如[123456789]可以匹配1~9。
如果规定一个7~8位数字的电话号码不能以0开头,规则:[123456789]\d{6,7}。
觉得把所有字符列出来太麻烦,[...]还有一种写法,直接写[1-9]就可以。
如果要匹配不限大小写的十六进制数,例如1A2b3c,可以这样写[0-9a-fA-F]。
如果要匹配6位十六进制数,前面讲过的{n}仍然可以继续配合使用:[0-9a-fA-F]{6}。
[...]还有一种排除法,能够不包含指定范围的字符。[^1-9],表示不匹配1~9之间的字符。
或规则匹配
用 | 连接的两个正则规则是或规则,例如,AB|CD表示可以匹配AB或CD。
使用括号
如果想要匹配字符串learn java、learn Vue 和 learn C#,一个规则是learn\sjava|learn\sVue|learn\sC#,但这样太麻烦了,可以把公共部分提出来,然后用(...)把其表示成learn\s(java|Vue|C#)。
复杂匹配规则主要有:
正则表达式 | 规则 | 可以匹配 |
---|---|---|
^ | 开头 | 字符串开头 |
$ | 结尾 | 字符串结束 |
[ABC] | […]内任意字符 | A,B,C |
[A-F0-9xy] | 指定范围的字符 | A ,……,F ,0 ,……,9 ,x ,y |
[^A-F] | 指定范围外的任意字符 | 非A ~F |
AB|CD|EF | AB或CD或EF | AB ,CD ,EF |
分组匹配
(...)还有一个重要作用就是分组匹配。
我们来看一下如何用正则匹配区号-电话号这个规则,利用匹配规则,可以写出:
提示:中间-前的\也是转义字符
\d{3,4}\-\d{6,8}
但如何分别提取出区号和电话号呢,我们可以先把上述正则表达式变为
(\d{3,4})\-(\d{6,8})
之后要按括号提取字符串,必须要用到java.util.regex包,用Pattern对象匹配,匹配后获得一个Matcher对象,如果匹配成功,就可以直接从Matcher.group(index)返回字符串:
要特别注意,Matcher.group(index)方法的参数用1表示第一个子串,2表示第二个子串。如果我们传入0会得到什么呢?答案是010-12345678,即整个正则匹配到的字符串。
使用Matcher时,必须首先调用matches()判断是否匹配成功,匹配成功后,才能调用group()提取子串。
非贪婪匹配
正则表达式默认使用贪婪匹配:任何一个规则,它总是尽可能多地向后匹配。
例如:我们给定一个字符串表示的数字,判断该数字末尾0的个数。
123000, 该正则表达式为:(\d+)(0*)
发现并没有如我们期望的那样分组。
实际上它是完全合理的,因为\d+确实可以匹配后面任意个0。
这是因为正则表达式默认使用贪婪匹配:任何一个规则,它总是尽可能多地向后匹配,因此,\d+总是会把后面的0包含进来。
要让\d+尽量少匹配,让0*尽量多匹配,我们就必须让\d+使用非贪婪匹配。在规则\d+后面加个?即可表示非贪婪匹配。
因此,给定一个匹配规则,加上?后就变成了非贪婪匹配。
注意:?的含义并不相同,\d?表示匹配0个或1个数字,\d??后面的?表示非贪婪匹配。
标签:字符,java,匹配,正则表达式,可以,记录,规则,06 From: https://blog.csdn.net/cwtlw/article/details/143747544