您的位置:首页 > 编程语言 > Java开发

正则表达式-常用构造子列表

2015-12-12 00:00 190 查看
摘要: 对正则表达式中常用的构造子列表进行整理。正则表达式的完整构造子列表,请参考JDK文档java.util.regex包中的Pattern类。

字符

表示单个字符。例如a,它将匹配字符串中第一次出现的字符a;它也可以匹配第二个 a,这必须是你告诉正则表达式引擎从第一次匹配的地方开始搜索。

可以使用特殊字符序列代表某些不可显示字符。

构造匹配
B字符B
\xhh十六进制值为oxhh的字符
\uhhhh十六进制值为oxhhhh的Unicode字符
\t制表符Tab:(‘\u0009’)
\r回车符:(‘\u000D’)
\n换行符:(‘\u000A’)
\f换页符:(‘\u000C’)
\e转义符(Escape):(‘\u001B’)

字符集

字符集是由一对括号[]括起来的字符集合。使用字符集,可以告诉正则表达式引擎仅仅匹配多个字符中的一个。

字符集可以出现在其它字符集中,并且可以包含并集运算符(隐式)和交集运算符 (&&)。

构造匹配
[abc]a、b或c(等效于a|b|c)
[^abc]除了a、b或c的任何字符(否定)
[a-zA-Z]a到z或A到Z的任何字符(范围)
[abc[hij]]a、b、c、h、i或j,等效于a|b|c|h|i|j(并集)
[a-z&&[hij]]h、i或j(交集)
并集和交集的应用示例如下:

[a-c[h-j]]

a到c或h到j的任何字符(并)

[a-z&&[^hij]]

a到z,除了h、i、j(减去),等效于[a-gk-z]

[a-z&&[^h-j]]

a到z,而非h到j(减去),等效于[a-gk-z]

预定义字符集

预定义字符集可以用在方括号之内或之外。

例如\s\d匹配一个空白符后面紧跟一个数字;[\s\d]匹配单个空白符或数字。

构造匹配
\d数字:[0-9]
\D非数字:[^0-9]
\s空白字符:空格、制表、回车、换行、换页
\S非空白字符:[^\s]
\w单词字符:[a-zA-Z_0-9]
\W非单词字符:[^\w]

边界匹配符

构造匹配
^输入序列的开始
当启用多行模式后,还可以匹配行的开始
$输入序列的结尾
当启用多行模式后,还可以匹配行的结尾
\b单词边界

\b匹配的是位置,这种匹配是0长度的

\b匹配一个“字母数字下划线”序列的开始和结束位置,在开始位置前面的字符或结束位置后面的字符不能是字母、数字或下划线

\B非单词边界:[^\b]
\B匹配的位置是两个“单词字符”之间或两个“非单词字符”之间的位置
\G上一个匹配的结尾

逻辑操作符

构造匹配
XYX后跟Y
X|YX或Y
匹配分支条件时,将会从左到右地测试每个条件,如果满足了某个分支的话,就不会去再管其它的条件了。例如\d{5}|\d{5}-\d{4},只会匹配5位数字以及9位数字的前5位
(X)捕获组(capturing group)。可以在表达式中用\i引用第i个捕获组

量词

量词描述了一个模式吸收输入文本的模式。

贪婪型:量词总是贪婪的,除非有其它的选项被设置。贪婪表达式会为所有可能的模式发现尽可能多的匹配。

懒惰型:懒惰型表达式匹配满足模式所需的最少字符数。

占有型:目前,占有型量词只在Java语言中可用。当正则表达式被应用于字符串时,它会产生相当多的状态,以便在匹配失败时可以回溯。而占有型量词并不保存这些中间状态,因此它可以防止回溯。它们常常用来防止正则表达式失控,因此可以使正则表达式执行起来更有效。

贪婪型懒惰型占有型如何匹配
X?X??X?+0次或1次X(等效于X{0,1})
事实上表示前导字符是可选的
X*X*?X*+0次或多次X(等效于X{0,} )
事实上表示前导字符可以出现任意次数
X+X+?X++1次或多次X(等效于X{1,} )
事实上表示前导字符至少重现1次
X{n}X{n}?X{n}+恰好n次X
X{n,}X{n,}?X{n,}+至少n次X
X{n,m}X{n,m}?X{n,m}+X至少n次,且不超过m次
量词的贪婪性

量词?+*会导致正则表达式引擎尽可能的重复前导字符。只有当这种重复会引起整个正则表达式匹配失败的情况下,引擎会进行回溯。也就是说,它会放弃最后一次的“重复”,然后处理正则表达式余下的部分。

例如,用一个正则表达式匹配一个HTML标签。

输入字符串为”This is a <EM>first</EM> test”,正则表达式<.+>返回”<EM>first</EM>”。这是因为+是贪婪性的。

让我们来看看正则引擎的处理过程。

正则表达式的第一个符号是“<”,这是一个字符;第二个符号是“.”,匹配了字符“E”;第三个符号是“+”,它可以一直可以匹配后面的字符,直到一行的结束;然后遇到了换行符,匹配失败(“.”不匹配换行符)。于是引擎开始对下一个正则表达式符号进行匹配,也即试图匹配“>”。到目前为止,正则表达式“<.+”已经匹配了“<EM>first</EM> test”。引擎会试图将“>”与换行符进行匹配,结果失败了。于是引擎进行回溯,“<.+”匹配“<EM>first</EM> tes”,于是引擎将“>”与“t”进行匹配,显然还是会失败。这个过程继续,直到“<.+”匹配“<EM>first</EM”,“>”与“>”匹配。最后引擎找到了一个匹配的部分“<EM>first</EM>”。

因为正则导向的引擎是“急切的”,所以它会急着报告它找到的第一个匹配。而不是继续回溯,即使可能会有更好的匹配,例如“<EM>”。所以由于“+”的贪婪性,使得引擎返回了一个最长的匹配。

可以使用下列方式来解决量词的贪婪性带来的问题。

用懒惰性取代贪婪性。

输入字符串为”This is a <EM>first</EM> test”,正则表达式<.+?>返回”<EM>”。

让我们再来看看正则引擎的处理过程。

正则表达式符号“<”会匹配素如字符串的第一个“<”。下一个正则符号是“.”。这次是一个懒惰的“+?”来重复上一个字符,它会尽可能少的重复上一个字符。因此引擎匹配“.”和字符“E”,然后用“>”匹配“M”,结果失败了。引擎会进行回溯,和上一个例子不同,因为是惰性重复,所以引擎是扩展惰性重复而不是减少;于是“<.+”现在被扩展为“<EM”。引擎继续匹配下一个符号“>”。这次得到了一个成功匹配。引擎于是报告“<EM>”是一个成功的匹配。

惰性扩展的一个替代方案。

输入字符串为”This is a <EM>first</EM> test”,正则表达式<[^>]+>返回”<EM>”。

这是一个更好的替代方案。可以用一个贪婪重复与一个取反字符集<[^>]+>。之所以说这是一个更好的方案在于使用惰性重复时,引擎会在找到一个成功匹配前对每一个字符进行回溯。而使用取反字符集则不需要进行回溯。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  JavaSE 正则表达式