一、字符集合
字符集合,也可以叫做字符类,它允许我们从多个候选字符中提取一个满足条件的字符。它的语法形式有两种, [abcdef] 和 [a-f] 。虽然是集合,但每次只允许匹配一个单字符,如果要进行重复性匹配操作,就要借助“*”、“+”和花括号的功能了。让我们先学习一下[abcdef]这种形式的用法。
假如我们要对电话号码格式进行验证,以“+086-800-800-8888”为例,其中 +086 的加号和首位数字都是可选字符。现在,我们对号码的第二个字符进行分析,它是一个 0 至 9 的数字,字符集合的表示方法是[0123456789],它可以与 0 至 9 之间的任意一个字符进行匹配。接下来我们要做的就是确定每个部分的匹配次数, [0123456789]{3} 、 [0123456789]{3} 、 [0123456789]{3} 和 [0123456789]{4} 。又因为 086 的首位可选,所以,我们最终构造出来的正则表达式语法为 /+?[0123456789]{2,3}-[0123456789]{3}-[0123456789]{3}-[0123456789]{4} 。这里值得注意的地方是“+”需要转义,因为“+”是正则表达式的语法一部分,它是具有特殊含义的,无法被我们直接利用,如果要使用“+”,就要对它进行转义。转义后的“/+”能告诉正则表达式引擎,当前这个“+”不是语法具有特殊意义,只是一个字符“+”而已。
二、字符范围的表示
字符集合的第二种语法形式 [a-f] 可以简化连续字符的书写方法,上例中的 [0123456789] 就能够简化为 [0-9] ,这样,简化后的语法就成为 /+?[0-9]{2,3}-[0-9]{3}-[0-9]{3}-[0-9]{4} 。我们还可以混合使用字符集合的语法,来提高灵活性。如 [a-fuwy0-9] :
如果方括号内的“-”的两端不是表示范围开始和结束的字符的话,它就会被当作普通的“-”来处理。让我们再看一个例子。现在要从句子“Javascript includes built-in support for array, date, and Regular-expression objects.”中提取那些含有“-”的复合词。我们先采用字符集合的形式来匹配“-”,使用语法 [a-zA-z]+[-][a-zA-z]+ ,当然我们也可以直接写“-”来进行匹配 [a-zA-z]+-[a-zA-z]+ :
看了上面的例子有些读者可能会感到很奇怪,既然可以指定字符集合的范围,我们为什么不直接写 [A-z] ,而要采用 [a-zA-Z] 这种形式呢?这是因为在ASCII和Unicode字符集中,大小写字母的位置并不是连续的,它们之间还有六个其它字符,如下图所示:
三、使用补集^
前面的两种语法都是正常匹配时所要用到的,但是,如果我们想使一个不存在于字符集合中的字符满足匹配条件时,又该怎么实现呢?换一句话说,除了集合之外的所有字符都是我们想要匹配的字符,正则表达式提供了一种 [^abcf-i] 的语法形式。对于这种语法,我们可以先按照正常思路考虑 [abcf-i] 的含义,匹配 abc 中任意一字符和 f 至 i 之间的字符,然后转过来理解,不满足 abc 中任意一字符和 f 至 i 之间的字符的内容,都是我们想要匹配的目标。值得注意的是“^”必须紧挨在左方括号的右边,否则它就不具有特殊含义,只是普通的字符“^”而已。
四、选择
字符集合能够从多个候选字符中选中一个来与目标字符进行匹配,但是,如何提供多个连续的候选字符组合呢?在正则表达式中,就有一个提供这样功能的元字符“|”。它将我们要匹配的字符组合用“|”分隔开,然后在目标字符串中进行匹配,只要有与分隔部分的内容能够匹配上的话,就能进行匹配。
下面是一段人物众多的小笑话,要理解起来本来是很费劲儿的,但通过正则表达式 魔王|公主|没有人|曹操|鬼|靠|谁|上帝 把所有的人物角色全列出来,就容易理解得多了。
《喊破喉咙》 魔王 把 公主 带回了自己的城堡。 魔王 :你尽管喊破喉咙吧, 没有人 会来救你的! 公主 :破喉咙!破喉咙! 没有人 : 公主 !我来救你了! 魔王 :说 曹操 曹操 到! 曹操 : 魔王 ,你叫我干嘛?! 魔王 :哇勒!看到 鬼 了!! 鬼 : 靠 !被发现了! 靠 :胡说, 谁 发现我了! 谁 :关我屁事! 魔王 :Oh~my God! 上帝 : 谁 叫我?! 谁 : 没有人 叫你啊! 没有人 :我哪有!! 魔王 从此得了精神分裂症……
五、知识要点补充与巩固
到现在为止,我们已经学会了很多基本的样式匹配,下面表格中是对前面的知识内容的一个总结。
语法形式 语法含义A | 匹配一个单一字符“A” |
. | 匹配任意一个字符 |
? | 重复零次或一次 |
/? | 转义后的字符“?” |
* | 重复零次或更多次(贪婪模式) |
+ | 重复一次或更多次(贪婪模式) |
*? | 重复零次或更多次(懒惰模式) |
+? | 重复一次或更多次(懒惰模式) |
{n} | 重复 n 次 |
{n,} | 重复 n 次或更多次 |
{m,n} | 重复 m 到 n 次(贪婪模式) |
{m,n}? | 重复 m 到 n 次(懒惰模式) |
[abc] | 匹配“a”,“b”,“c”中的任意一个字符 |
[abcf-i] | 匹配“a”,“b”,“c”,“f”至“g”中的任意一个字符 |
[^1-37a-gx] | 匹配“1”至“3”,“7”,“a”至“g”,“x”之外的任意一个字符 |