java正则表达式.docx
《java正则表达式.docx》由会员分享,可在线阅读,更多相关《java正则表达式.docx(36页珍藏版)》请在冰豆网上搜索。
![java正则表达式.docx](https://file1.bdocx.com/fileroot1/2023-1/14/08e5cb49-1926-4a5a-be05-8d12ef717ff0/08e5cb49-1926-4a5a-be05-8d12ef717ff01.gif)
java正则表达式
Java正则表达式的解释说明
表达式意义:
1.字符
x字符x。
例如a表示字符a
\\反斜线字符。
在书写时要写为\\\\。
(注意:
因为java在第一次解析时,把\\\\解析成正则表达式\\,在第二次解析时再解析为\,所以凡是不是1.1列举到的转义字符,包括1.1的\\,而又带有\的都要写两次)
\0n带有八进制值0的字符n(0<=n<=7)
\0nn带有八进制值0的字符nn(0<=n<=7)
\0mnn带有八进制值0的字符mnn(0<=m<=3、0<=n<=7)
\xhh带有十六进制值0x的字符hh
\uhhhh带有十六进制值0x的字符hhhh
\t制表符('\u0009')
\n新行(换行)符('\u000A')
\r回车符('\u000D')
\f换页符('\u000C')
\a报警(bell)符('\u0007')
\e转义符('\u001B')
\cx对应于x的控制符
2.字符类
[abc]a、b或c(简单类)。
例如[egd]表示包含有字符e、g或d。
[^abc]任何字符,除了a、b或c(否定)。
例如[^egd]表示不包含字符e、g或d。
[a-zA-Z]a到z或A到Z,两头的字母包括在内(范围)
[a-d[m-p]]a到d或m到p:
[a-dm-p](并集)
[a-z&&[def]]d、e或f(交集)
[a-z&&[^bc]]a到z,除了b和c:
[ad-z](减去)
[a-z&&[^m-p]]a到z,而非m到p:
[a-lq-z](减去)
3.预定义字符类(注意反斜杠要写两次,例如\d写为\\d)任何字符
(与行结束符可能匹配也可能不匹配)
\d数字:
[0-9]
\D非数字:
[^0-9]
\s空白字符:
[\t\n\x0B\f\r]
\S非空白字符:
[^\s]
\w单词字符:
[a-zA-Z_0-9]
\W非单词字符:
[^\w]
4.POSIX字符类(仅US-ASCII)(注意反斜杠要写两次,例如\p{Lower}写为\\p{Lower})
\p{Lower}小写字母字符:
[a-z]。
\p{Upper}大写字母字符:
[A-Z]
\p{ASCII}所有ASCII:
[\x00-\x7F]
\p{Alpha}字母字符:
[\p{Lower}\p{Upper}]
\p{Digit}十进制数字:
[0-9]
\p{Alnum}字母数字字符:
[\p{Alpha}\p{Digit}]
\p{Punct}标点符号:
!
"#$%&'()*+,-./:
;<=>?
@[\]^_`{|}~
\p{Graph}可见字符:
[\p{Alnum}\p{Punct}]
\p{Print}可打印字符:
[\p{Graph}\x20]
\p{Blank}空格或制表符:
[\t]
\p{Cntrl}控制字符:
[\x00-\x1F\x7F]
\p{XDigit}十六进制数字:
[0-9a-fA-F]
\p{Space}空白字符:
[\t\n\x0B\f\r]
5.java.lang.Character类(简单的java字符类型)
\p{javaLowerCase}等效于java.lang.Character.isLowerCase()
\p{javaUpperCase}等效于java.lang.Character.isUpperCase()
\p{javaWhitespace}等效于java.lang.Character.isWhitespace()
\p{javaMirrored}等效于java.lang.Character.isMirrored()
6.Unicode块和类别的类
\p{InGreek}Greek块(简单块)中的字符
\p{Lu}大写字母(简单类别)
\p{Sc}货币符号
\P{InGreek}所有字符,Greek块中的除外(否定)
[\p{L}&&[^\p{Lu}]]所有字母,大写字母除外(减去)
7.边界匹配器
^行的开头,请在正则表达式的开始处使用^。
例如:
^(abc)表示以abc开头的字符串。
注意编译的时候要设置参数MULTILINE,如Patternp=Ppile(regex,Pattern.MULTILINE);
$行的结尾,请在正则表达式的结束处使用。
例如:
(^bca).*(abc$)表示以bca开头以abc结尾的行。
\b单词边界。
例如\b(abc)表示单词的开始或结束包含有abc,(abcjj、jjabc都可以匹配)
\B非单词边界。
例如\B(abc)表示单词的中间包含有abc,(jjabcjj匹配而jjabc、abcjj不匹配)
\A输入的开头
\G上一个匹配的结尾(个人感觉这个参数没什么用)。
例如\\Gdog表示在上一个匹配结尾处查找dog如果没有的话则从开头查找,注意如果开头不是dog则不能匹配。
\Z输入的结尾,仅用于最后的结束符(如果有的话)
行结束符是一个或两个字符的序列,标记输入字符序列的行结尾。
以下代码被识别为行结束符:
‐新行(换行)符('\n')、
‐后面紧跟新行符的回车符("\r\n")、
‐单独的回车符('\r')、
‐下一行字符('\u0085')、
‐行分隔符('\u2028')或
‐段落分隔符('\u2029)。
\z输入的结尾
当编译模式时,可以设置一个或多个标志,例如
Patternpattern=Ppile(patternString,Pattern.CASE_INSENSITIVE+Pattern.UNICODE_CASE);
下面六个标志都是支持的:
‐CASE_INSENSITIVE:
匹配字符时与大小写无关,该标志默认只考虑USASCII字符。
‐UNICODE_CASE:
当与CASE_INSENSITIVE结合时,使用Unicode字母匹配
‐MULTILINE:
^和$匹配一行的开始和结尾,而不是整个输入
‐UNIX_LINES:
当在多行模式下匹配^和$时,只将'\n'看作行终止符
‐DOTALL:
当使用此标志时,.符号匹配包括行终止符在内的所有字符
‐CANON_EQ:
考虑Unicode字符的规范等价
8.Greedy数量词
X?
X,一次或一次也没有
X*X,零次或多次
X+X,一次或多次
X{n}X,恰好n次
X{n,}X,至少n次
X{n,m}X,至少n次,但是不超过m次
9.Reluctant数量词
X?
?
X,一次或一次也没有
X*?
X,零次或多次
X+?
X,一次或多次
X{n}?
X,恰好n次
X{n,}?
X,至少n次
X{n,m}?
X,至少n次,但是不超过m次
10.Possessive数量词
X?
+X,一次或一次也没有
X*+X,零次或多次
X++X,一次或多次
X{n}+X,恰好n次
X{n,}+X,至少n次
X{n,m}+X,至少n次,但是不超过m次
Greedy,Reluctant,Possessive的区别在于:
(注意仅限于进行.等模糊处理时)
greedy量词被看作“贪婪的”,因为它第一次就读入整个被模糊匹配的字符串。
如果第一个匹配尝试(整个输入字符串)失败,匹配器就会在被匹配字符串中的最后一位后退一个字符并且再次尝试,重复这个过程,直到找到匹配或者没有更多剩下的字符可以后退为止。
根据表达式中使用的量词,它最后试图匹配的内容是1个或者0个字符。
但是,reluctant量词采取相反的方式:
它们从被匹配字符串的开头开始,然后逐步地一次读取一个字符搜索匹配。
它们最后试图匹配的内容是整个输入字符串。
最后,possessive量词总是读完整个输入字符串,尝试一次(而且只有一次)匹配。
和greedy量词不同,possessive从不后退。
11.Logical运算符
XYX后跟Y
X|YX或Y
(X)X,作为捕获组。
例如(abc)表示把abc作为一个整体进行捕获
12.Back引用
\n任何匹配的nth捕获组
捕获组可以通过从左到右计算其开括号来编号。
例如,在表达式((A)(B(C)))中,存在四个这样的组:
1((A)(B(C)))
2\A
3(B(C))
4(C)
在表达式中可以通过\n来对相应的组进行引用,例如(ab)34\1就表示ab34ab,(ab)34(cd)\1\2就表示ab34cdabcd。
13.引用
\Nothing,但是引用以下字符
\QNothing,但是引用所有字符,直到\E。
QE之间的字符串会原封不动的使用(1.1中转义字符的除外)。
例如,ab\\Q{|}\\\\E
可以匹配ab{|}\\
\ENothing,但是结束从\Q开始的引用
14.特殊构造(非捕获)
(?
:
X)X,作为非捕获组
(?
idmsux-idmsux)Nothing,但是将匹配标志由on转为off。
比如:
表达式(?
i)abc(?
-i)def这时,(?
i)打开不区分大小写开关,abc匹配
idmsux说明如下:
‐iCASE_INSENSITIVE:
US-ASCII字符集不区分大小写。
(?
i)
‐dUNIX_LINES:
打开UNIX换行符
‐mMULTILINE:
多行模式(?
m)
UNIX下换行为\n
WINDOWS下换行为\r\n(?
s)
‐uUNICODE_CASE:
Unicode不区分大小写。
(?
u)
‐xCOMMENTS:
可以在pattern里面使用注解,忽略pattern里面的whitespace,以及"#"一直到结尾(#后面为注解)。
(?
x)例如(?
x)abc#asfsdadsa可以匹配字符串abc
(?
idmsux-idmsux:
X)X,作为带有给定标志on-off的非捕获组。
与上面的类似,上面的表达式,可以改写成为:
(?
i:
abc)def,或者(?
i)abc(?
-i:
def)
(?
=X)X,通过零宽度的正lookahead。
零宽度正先行断言,仅当子表达式X在此位置的右侧匹配时才继续匹配。
例如,\w+(?
=\d)表示字母后面跟数字,但不捕获数字(不回溯)
(?
!
X)X,通过零宽度的负lookahead。
零宽度负先行断言。
仅当子表达式X不在此位置的右侧匹配时才继续匹配。
例如,\w+(?
!
\d)表示字母后面不跟数字,且不捕获数字。
(?
<=X)X,通过零宽度的正lookbehind。
零宽度正后发断言。
仅当子表达式X在此位置的左侧匹配时才继续匹配。
例如,(?
<=19)99表示99前面是数字19,但不捕获前面的19。
(不回溯)
(?
(?
>X)X,作为独立的非捕获组(不回溯)
(?
=X)与(?
>X)的区别在于(?
>X)是不回溯的。
例如被匹配的字符串为abcm
当表达式为a(?
:
b|bc)m是可以匹配的,而当表达式是a(?
>b|bc)时是不能匹配的,因为当后者匹配到b时,由于已经匹配,就跳出了非捕获组,而不再次对组内的字符进行匹配。
可以加快速度。
注意:
有评论说最后一句说的有问题——“这里有问题!
abcm也可被a(?
>b|bc)匹配!
”
引言
正则表达式(regularexpression)就是用一个“字符串”来描述一个特征,然后去验证另一个“字符串”是否符合这个特征。
比如表达式“ab+”描述的特征是“一个'a'和任意个'b'”,那么'ab','abb','abbbbbbbbbb'都符合这个特征。
正则表达式可以用来:
(1)验证字符串是否符合指定特征,比如验证是否是合法的邮件地址。
(2)用来查找字符串,从一个长的文本中查找符合指定特征的字符串,比查找固定字符串更加灵活方便。
(3)用来替换,比普通的替换更强大。
正则表达式学习起来其实是很简单的,不多的几个较为抽象的概念也很容易理解。
之所以很多人感觉正则表达式比较复杂,一方面是因为大多数的文档没有做到由浅入深地讲解,概念上没有注意先后顺序,给读者的理解带来困难;另一方面,各种引擎自带的文档一般都要介绍它特有的功能,然而这部分特有的功能并不是我们首先要理解的。
文章中的每一个举例,都可以点击进入到测试页面进行测试。
闲话少说,开始。
1.正则表达式规则
1.1普通字符
字母、数字、汉字、下划线、以及后边章节中没有特殊定义的标点符号,都是"普通字符"。
表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。
举例1:
表达式"c",在匹配字符串"abcde"时,匹配结果是:
成功;匹配到的内容是:
"c";匹配到的位置是:
开始于2,结束于3。
(注:
下标从0开始还是从1开始,因当前编程语言的不同而可能不同)
举例2:
表达式"bcd",在匹配字符串"abcde"时,匹配结果是:
成功;匹配到的内容是:
"bcd";匹配到的位置是:
开始于1,结束于4。
1.2简单的转义字符
一些不便书写的字符,采用在前面加"\"的方法。
这些字符其实我们都已经熟知了。
表达式
可匹配
\r,\n
代表回车和换行符
\t
制表符
\\
代表"\"本身
还有其他一些在后边章节中有特殊用处的标点符号,在前面加"\"后,就代表该符号本身。
比如:
^,$都有特殊意义,如果要想匹配字符串中"^"和"$"字符,则表达式就需要写成"\^"和"\$"。
表达式
可匹配
\^
匹配^符号本身
\$
匹配$符号本身
\.
匹配小数点(.)本身
这些转义字符的匹配方法与"普通字符"是类似的。
也是匹配与之相同的一个字符。
举例1:
表达式"\$d",在匹配字符串"abc$de"时,匹配结果是:
成功;匹配到的内容是:
"$d";匹配到的位置是:
开始于3,结束于5。
1.3能够与'多种字符'匹配的表达式
正则表达式中的一些表示方法,可以匹配'多种字符'其中的任意一个字符。
比如,表达式"\d"可以匹配任意一个数字。
虽然可以匹配其中任意字符,但是只能是一个,不是多个。
这就好比玩扑克牌时候,大小王可以代替任意一张牌,但是只能代替一张牌。
表达式
可匹配
\d
任意一个数字,0~9中的任意一个
\w
任意一个字母或数字或下划线,也就是A~Z,a~z,0~9,_中任意一个
\s
包括空格、制表符、换页符等空白字符的其中任意一个
.
小数点可以匹配除了换行符(\n)以外的任意一个字符
举例1:
表达式"\d\d",在匹配"abc123"时,匹配的结果是:
成功;匹配到的内容是:
"12";匹配到的位置是:
开始于3,结束于5。
举例2:
表达式"a.\d",在匹配"aaa100"时,匹配的结果是:
成功;匹配到的内容是:
"aa1";匹配到的位置是:
开始于1,结束于4。
1.4自定义能够匹配'多种字符'的表达式
使用方括号[]包含一系列字符,能够匹配其中任意一个字符。
用[^]包含一系列字符,则能够匹配其中字符之外的任意一个字符。
同样的道理,虽然可以匹配其中任意一个,但是只能是一个,不是多个。
表达式
可匹配
[ab5@]
匹配"a"或"b"或"5"或"@"
[^abc]
匹配"a","b","c"之外的任意一个字符
[f-k]
匹配"f"~"k"之间的任意一个字母
[^A-F0-3]
匹配"A"~"F","0"~"3"之外的任意一个字符
举例1:
表达式"[bcd][bcd]"匹配"abc123"时,匹配的结果是:
成功;匹配到的内容是:
"bc";匹配到的位置是:
开始于1,结束于3。
举例2:
表达式"[^abc]"匹配"abc123"时,匹配的结果是:
成功;匹配到的内容是:
"1";匹配到的位置是:
开始于3,结束于4。
1.5修饰匹配次数的特殊符号
前面章节中讲到的表达式,无论是只能匹配一种字符的表达式,还是可以匹配多种字符其中任意一个的表达式,都只能匹配一次。
如果使用表达式再加上修饰匹配次数的特殊符号,那么不用重复书写表达式就可以重复匹配。
使用方法是:
"次数修饰"放在"被修饰的表达式"后边。
比如:
"[bcd][bcd]"可以写成"[bcd]{2}"。
表达式
作用
{n}
表达式重复n次,比如:
"\w{2}"相当于"\w\w";"a{5}"相当于"aaaaa"
{m,n}
表达式至少重复m次,最多重复n次,比如:
"ba{1,3}"可以匹配"ba"或"baa"或"baaa"
{m,}
表达式至少重复m次,比如:
"\w\d{2,}"可以匹配"a12","_456","M12344"...
?
匹配表达式0次或者1次,相当于{0,1},比如:
"a[cd]?
"可以匹配"a","ac","ad"
+
表达式至少出现1次,相当于{1,},比如:
"a+b"可以匹配"ab","aab","aaab"...
*
表达式不出现或出现任意次,相当于{0,},比如:
"\^*b"可以匹配"b","^^^b"...
举例1:
表达式"\d+\.?
\d*"在匹配"Itcosts$12.5"时,匹配的结果是:
成功;匹配到的内容是:
"12.5";匹配到的位置是:
开始于10,结束于14。
举例2:
表达式"go{2,8}gle"在匹配"Adsbygoooooogle"时,匹配的结果是:
成功;匹配到的内容是:
"goooooogle";匹配到的位置是:
开始于7,结束于17。
1.6其他一些代表抽象意义的特殊符号
一些符号在表达式中代表抽象的特殊意义:
表达式
作用
^
与字符串开始的地方匹配,不匹配任何字符
$
与字符串结束的地方匹配,不匹配任何字符
\b
匹配一个单词边界,也就是单词和空格之间的位置,不匹配任何字符
进一步的文字说明仍然比较抽象,因此,举例帮助大家理解。
举例1:
表达式"^aaa"在匹配"xxxaaaxxx"时,匹配结果是:
失败。
因为"^"要求与字符串开始的地方匹配,因此,只有当"aaa"位于字符串的开头的时候,"^aaa"才能匹配,比如:
"aaaxxxxxx"。
举例2:
表达式"aaa$"在匹配"xxxaaaxxx"时,匹配结果是:
失败。
因为"$"要求与字符串结束的地方匹配,因此,只有当"aaa"位于字符串的结尾的时候,"aaa$"才能匹配,比如:
"xxxxxxaaa"。
举例3:
表达式".\b."在匹配"@@@abc"时,匹配结果是:
成功;匹配到的内容是:
"@a";匹配到的位置是:
开始于2,结束于4。
进一步说明:
"\b"与"^"和"$"类似,本身不匹配任何字符,但是它要求它在匹配结果中所处位置的左右两边,其中一边是"\w"范围,另一边是非"\w"的范围。
举例4:
表达式"\bend\b"在匹配"weekend,endfor,end"时,匹配结果是:
成功;匹配到的内容是:
"end";匹配到的位置是:
开始于15,结束于18。
一些符号可以影响表达式内部的子表达式之间的关系:
表达式
作用
|
左右两边表达式之间"或"关系,匹配左边或者右边
()
(1).在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰
(2).取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到
举例5:
表达式"Tom|Jack"在匹配字符串"I'mTom,heisJack"时,匹配结果是:
成功;匹配到的内容是:
"Tom";匹配到的位置是:
开始于4,结束于7。
匹配下一个时,匹配结果是:
成功;匹配到的内容是:
"Jack";匹配到的位置时:
开始于15,结束于19。
举例6:
表达式"(go\s*)+"在匹配"Let'sgogogo!
"时,匹配结果是:
成功;匹配到内容是:
"gogogo";匹配到的位置是:
开始于6,结束于14。
举例7:
表达式"¥(\d+\.?
\d*)"在匹配"$10.9,¥20.5"时,匹配的结果是:
成功;匹配到的内容是:
"¥20.5";匹配到的位置是:
开始于6,结束于10。
单独获取括号范围匹配到的内容是:
"20.5"。
2.正则表达式中的一些高级规则
2.1匹配次数中的贪婪与非贪婪
在使用修饰匹配次数的特殊符号时,有几种表示方法可以使同一个表达式能够匹配不同的次数,比如:
"{m,n}","{m,}","?
","*","+",具体匹配的次数随被匹配的字符串而定。
这种重复匹配不定次数的表达式在匹配过程中,总是尽可能多的匹配。
比如,针对文本"dxxxdxxxd",举例如下:
表达式
匹配结果
(d)(\w+)
"\w+"将匹配第一个"d"之后的所有字符"xxxdxxxd"
(d)(\w+)(d)
"\w+"将匹配第一个"d"和最后一个"d"之间的所有字符"xxxdxxx"。
虽然"\w+"也能够匹配上最后一个"d",但是为了使整个表达式匹配成功,"\w+"可以"让出"它本来能够匹配的最后一个"d"
由此可见,"\w+"在匹配的时候,总是尽可能多的匹配符合它规则的字符。
虽然第二个举例中,它没有匹配最后一个"d",但那也是为了让整个表达式能够匹配成功。
同理,带"*"和"{m,n}"的表达式都是尽可能地多匹配,带"?
"的表达式在可匹配可不匹配的时候,也是尽可能的"要匹配"。
这种匹配原则就叫作"贪婪"模式。
非贪婪模式:
在修饰匹配次数的特殊符号后再加上一个"?
"号,则可以使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式,尽可能的"不匹配"。
这种匹配原则叫作"非贪婪"模式,也叫作"勉强"模式。
如果少匹配就会导致整个表达式匹配失败的时候,与贪婪模式类似,非贪婪模式会最小限度的再匹配一些,以使整个表达式匹配成功。
举例如下,针对文本"dxxxdxxxd"举例:
表达式
匹配结果
(d)(\w+?
)
"\w+?
"将尽可能少的匹配第一个"d"之后的字符,结果是:
"\w+?
"只匹配了一个"x"
(d)(\w+?
)(d)
为了让整个表达式匹配成功,"\w+?
"不得不匹配"xxx"才可以让后边的"d"匹配,从而使整个表达式匹配成功。
因此,结果是:
"\w+?
"匹配"xxx"
更多的情况,举例如下:
举例1:
表达式"
(.*) | "与字符串"
aa | bb | "匹配时,匹配的结果是:
成功;匹配到的内容是"
aa | bb | "整个字符串,表达式中的""将与字符串中最后一个""匹配。
举例2:
相比之下,表达式"
(.*? ) | "匹配举例1中同样的字符串时,将只得到"
aa | ",再次匹配下一个