![](https://csdnimg.cn/release/download_crawler_static/10524000/bg4.jpg)
字符集的重复
如果你用“?*+”操作符来重复一个字符集,你将会重复整个字符集。而不仅是它匹配的
那个字符。正则表达式<<[0-9]+>>会匹配 837 以及 222。
如果你仅仅想重复被匹配的那个字符,可以用向后引用达到目的。我们以后将讲到向后引
用。
6. 使用?*或+ 进行重复
?:告诉引擎匹配前导字符 0 次或一次。事实上是表示前导字符是可选的。
+:告诉引擎匹配前导字符 1 次或多次
*:告诉引擎匹配前导字符 0 次或多次
<[A-Za-z][A-Za-z0-9]*>匹配没有属性的 HTML 标签,“<”以及“>”是文字符号。
第一个字符集匹配一个字母,第二个字符集匹配一个字母或数字。
我们似乎也可以用<[A-Za-z0-9]+>。但是它会匹配<1>。但是这个正则表达式在你知道
你要搜索的字符串不包含类似的无效标签时还是足够有效的。
限制性重复
许多现代的正则表达式实现,都允许你定义对一个字符重复多少次。词法是:{min,max}。
min 和 max 都是非负整数。如果逗号有而 max 被忽略了,则 max 没有限制。如果逗号和 max
都被忽略了,则重复 min 次。
因此{0,}和*一样,{1,}和+ 的作用一样。
你可以用<<\b[1-9][0-9]{3}\b>>匹配 1000~9999 之间的数字(“\b”表示单词边界)。
<<\b[1-9][0-9]{2,4}\b>>匹配一个在 100~99999 之间的数字。
注意贪婪性
假设你想用一个正则表达式匹配一个 HTML 标签。你知道输入将会是一个有效的 HTML 文
件,因此正则表达式不需要排除那些无效的标签。所以如果是在两个尖括号之间的内容,就应该
是一个 HTML 标签。
许多正则表达式的新手会首先想到用正则表达式<< <.+> >>,他们会很惊讶的发现,对
于测试字符串,“This is a <EM>first</EM> test”,你可能期望会返回<EM>,然后继续
进行匹配的时候,返回</EM>。
但事实是不会。正则表达式将会匹配“<EM>first</EM>”。很显然这不是我们想要的结
果。原因在于“+”是贪婪的。也就是说,“+”会导致正则表达式引擎试图尽可能的重复前导
字符。只有当这种重复会引起整个正则表达式匹配失败的情况下,引擎会进行回溯。也就是说,
它会放弃最后一次的“重复”,然后处理正则表达式余下的部分。
和“+”类似,“?*”的重复也是贪婪的。
深入正则表达式引擎内部
让我们来看看正则引擎如何匹配前面的例子。第一个记号是“<”,这是一个文字符号。第
二个符号是“.”,匹配了字符“E”,然后“+”一直可以匹配其余的字符,直到一行的结束。
然后到了换行符,匹配失败(“.”不匹配换行符)。于是引擎开始对下一个正则表达式符号进行
匹配。也即试图匹配“>”。到目前为止,“<.+”已经匹配了“<EM>first</EM> test”。
引擎会试图将“>”与换行符进行匹配,结果失败了。于是引擎进行回溯。结果是现在“<.+”
匹配“<EM>first</EM> tes”。于是引擎将“>”与“t”进行匹配。显然还是会失败。这个