正则表达式匹配任意符——点号
元字符 "/./"
是用来匹配任意字符的字符组的简写方法。如果需要在正则表达式中使用一个“匹配任何字符”的占位符,用点号就很方便。 记住:字符组内部和字符组外面,元字符的定义和意义是不一样的。 在 /03[-./]19[-./]6/
中,点号并不是元字符,这里的连字符同样也不是元字符,因为它们都紧接在 [或者[^
之后。如果连字符不在字符组开头,例如 [.-/]
,就是用来表示范围的。
正则表达式-多选结构
匹配任意子表达式
符号 /|/
在正则表达式中是一个简捷的元字符,学过编程的都知道 |
在代码中是"或"的意思。通过它,我们能够把不同的子表达式祝贺成一个总的表达式,而这个 总的表达式又能够匹配任意子表达式。假如:/Bob/
和 /Robert/
是两个表达式,但是 /Bob|Robert/
就是能够同时匹配其中任意一个的 正则表达式。在这样的组合中,子表达式被称为"多选分之"。
现在我们回到以前的一个颜色例子:/gr[ea]y/
这个例子中,我们也可以写作:/grey|gray/
或者 /gr(a|e)y/
。**(请注意了:多选分子的元字符 |,分割的是这个符号的前后,所以如果在正则表达式中需要使用多选分之的时候,注意括号的使用。比如我要匹配一个图片标签,图片标签它可能是这样的两种:`
、
,那么这个正则表达式该这样:
//),当然了也可以这样
//`。**
对表达式 /gr(e|a)y/
来说,括号是必须的,没有括号就成了匹配 /gre/
或者 /ay/
了,这显然不符合我们的需求。多选结构可以包括很多字符,但不能超越括号的界限。
注意这两个正则表达式:/gr[ea]y/
与 /gr(e|a)y/
,这两个例子可能让人觉得多选结构与字符组没有太大的区别,但是千万别混淆这两个概念。 一个字符组只能匹配目标文中的 单个字符 ,而每个多选结构自身都可能是一个完整的正则表达式,都可以匹配任意长度的文本。字符组基本可以算是一门独立的微型语言 (例如,对于元字符,它们有自己的规定),而多选结构是"正则表达式语言主体"的一部分。随着深入运用,你会发现这两者都很有用处。
同样的,在一个包含多选结构的表达式中使用脱字符和美元符也要特别小心。比较 /^From|Subject|Date:/
和 /^(From|Subject|Date):/
就会发现,它们虽然看起来都很相似,但是匹配结果却大不相同。第一个表达式中由三个 多选分支构成,所以他能匹配 /^From/
或者 /Subject/
或者 /Date:/
,实用性不大。我们希望在每一个分支钱都有一个脱字符,之后都有一个 /:/
。 所以,应该使用括号来限制这些多选分子:
/^(From|Subject|Date):/
现在,这 3 个多选分支都受到括号的限制,所以这个正则表达式的意思是:匹配以 From 或者 Subject 或者 Date 开头然后匹配 :
。
忽略大小写
基本的,忽略大小写,就是利用 i
这个参数,在 PHP 中,忽略大小写的正则表达式可以这样写 /bob/i
,我经常在处理 HTML TAG 的时候使用 i
参数。
单词分界符
使用正则表达式时经常会遇到一个问题,期望匹配的"单词"包含在另一个单词之间。在 cat、gray、Smith 的例子中,我提到过这个问题。不过某些版本的 egrep 对单词识别提供了 有限的支持:也就是单词分界符(单词开头和结束位置)的匹配。
如果你的 egrep 支持"元字符序列"/\/
,就可以使用它们来匹配单词分界的位置。比如正则表达式 /\/
的意思就是匹配单词的开头位置,然后是 cat 这三个字母,然后是单词结束的位置。如果你不这么理解也可以理解为匹配 cat 这个单词。
请注意,
< 和 >
并不是元字符,只有当它们与斜线结合起来的时候,整个序列才具有特殊意义。重要的是特殊意义,而不是字符的个数,有时有"元字符"和元(字符)序列是等价的。记住:并不是所有版本的 egrep 都支持单词分界符,即使支持的版本也不见得聪明到"认得出"单词。"单词的起始位置"只不过是一系列字母和数字符号开始的位置,而结束位置就是它们结尾的地方。前面的例子中,有写到
\> 和\<
,其实这是不必要加反斜线的,PHP 中不支持单词分界符,>< 在 PHP 正则表达式中也不是特殊字符。
小结
元字符 | 名称 | 匹配对象 |
---|---|---|
. |
点号 | 单个任意字符 |
[...] |
字符组 | 列出的任意字符 |
[^...] |
排除型字符组 | 未列出的任意字符 |
^ |
脱字符 | 行的起始位置 |
$ |
美元符 | 行的结束位置 |
\< |
反斜线-小于 | 单词的起始位置(某些版本的 egrep 可能不支持) |
\> |
反斜线-大于 | 单词的结束位置 (某些版本的 egrep 可能不支持) |
竖线 | 匹配分隔两边的任意一个表达式 | |
(...) |
括号 | 限制竖线的作用范围,其他的功能接下来讨论 |
另外还需要注意的:
- 在字符组内部,元字符的定义规则是不一样的。例如字符组外部点号是元字符,在内部则不是。相反的,连字符在字符组内部是元字符,否则不是。
- 不要混淆多选项和字符组,字符组
/[abc]/
和多选项/(a|b|c)/
在这里的效果固然一样,但是这个例子中的相似性并不能扩展。多选项没有排除功能,而字符组有排除功能。 - 排除型字符组是表示所有为列出字符的字符组的简便方法。因此,
/[^a]/
的意思并不是"只有当这个文字不是 a 的时候才能匹配",而是说"匹配一个不等于 a 的字符"。这里的差别很细微,但是很重要。比如前面的概念可以匹配一个空行,而/[^a]/
则不行。 - i 参数规定匹配时不区分大小写。