一、字符集合
字符集合,也可以叫做字符类,它允许我们从多个候选字符中提取一个满足条件的字符。它的语法形式有两种, [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”之外的任意一个字符 |

