可选项元素
元字符?
代表可选项,比如color
和colour
两个单词,只相差一个字符u
,可以用colou?r
来解决这个问题。把问号加在一个单词的后面,就表示此处容许出现这个字符,不过它的出现并非匹配成功的必要条件。
u?
这个元字符和我们之前看到的元字符都不同,它只作用于之前紧邻的元素例子:匹配7月4日:
(July|Jul)。(fourth|4th|4)
July?。(fourth|4th|4)
两个正则表达式都是可以正确匹配的。
现在我们来看第二部分,可以把4th|4
简化为4(th)?
。我们看到,现在?
作用的元素是整个括号了。括号内的表达式可以任意复杂,但是“从括号外来看”它们是一个整体。界定?
的作用对象(还可以划定的其他类似元字符的作用对象)是括号的主要功能之一。
正则表达式不是死板的教条,它更像是一门艺术。
其他量词:重复出现
加号+
星号*
和问号?
统称为量词,因为他们限定了所做用的元素的重现次数。
与...?
一样...*
也是永远不会匹配失败的,区别只在于它们的匹配结果。而...+
在无法进行任何一次匹配时,会报告匹配失败。
用上面三个量词来匹配空格数的例子:
。?
能够匹配一个可能出现的空格(这里用句号(。)表示空格,便于直观显示)。
。*
能够匹配任意个空格。
在HTML规范中标签内的空格数目不统一,可能出现任意空格,这时候可以用量词进行空格匹配找到标签。
例子:HTML标签<HR。SIZE=14>
这个标签,他表示一条高度为14像素的穿越整个屏幕的水平线。
- 在最后的尖括号之前可以出现任意个空格
- 在等号两边允许出现任意个空格
- 在
HR
和SIZE
之间必须至少有一个空格
一个合格的正则表达式可以是:<HR。+SIZE。*=。*14。*>
我们必须能匹配其他高度的线,所以要对14
进行匹配优化。在这里,“数值”是由一位或多位数字构成的。[0-9]
可以匹配任意一个数字,因为至少出现一次,所以使用加号量词,结果就是[0-9]+
替换14
,(一个字符组就是一个元素,可以对它使用量词,而不需要括号)。
简化后得到:<HR。+SIZE。*=。*[0-9]+。*>
。
如果尺寸是可选项,则正则表达式可以是:
<HR(。+SIZE。*=。*[0-9]+)?。*>
。这里要注意放在括号内外的内容。详细解释参见书20页的解释。
请注意:每个量词都规定了匹配成功至少需要的重现次数下限,以及尝试匹配的重现次数上限。
规定重现次数的范围:区间
...{min,max}
被称为“区间量词”。
括号及反向引用
括号已经了解的两个用途是:
- 限制多选项的范围
- 将若干字符组合为一个单元,受问号之类的量词的作用。
现在将介绍括号的第三个用途。在许多流派的正则表达式中,括号能“记住”它们包含的子表达式匹配的文本。
反向引用是正则表达式的特性之一,它允许我们匹配与先前部分匹配的同样的文本。
将括号和反向引用结合起来就可以了。
我们用元字符序列\1
记住括号内子表达式匹配的文本。如果有多个括号那么可以用\2
,\3
等来匹配。注意:括号是按照开括号(
从右至左得出现顺序进行的,所以([a-z]) ([0-9] \1\2)
中的\1
代表[a-z]
匹配的内容,而\2
代表[0-9]
匹配的内容。
匹配两个连续出现的单词的正则表达式为:\<([A-Za-z]+)。+\1\>
。
用上述正则匹配文本the。the
,[A-Za-z]+
匹配第一个the
。因为这个子表达式在括号中,所以\1
代表的文本就是the
。如果。+
能够匹配,后面的\1
要匹配的文本就是the
。如果\1
也能够匹配成功,最后的\>
对应单词的结尾(如果文本是the。theft
,这一条件就不满足)。如果整个表达式能够匹配成功,我们就得到了一个重复单词。有的重复单词并不是错误,如that that
,这时候要人来判断句子是不是错误。
神奇的转义
如果需要匹配的某个字符本身就是元字符,我们需要用转义。比如点号.
真正匹配的应该是元序列是反斜线加上点号\.
。这样的办法适用于所有元字符。
例子:\([a-zA-Z]+\)
匹配用括号括起来的单词。反斜线消除了括号的特殊意义。
如果反斜线后面的字符不是元字符,那么其意义由程序的版本而定。比如\1
,\<
,\>
。