ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

正则表达式——匹配一组字符

正则表达式——匹配一组字符

匹配一组字符

    • 1、匹配多个字符中的某一个
    • 2、利用字符集合区间
    • 3、取非匹配

1、匹配多个字符中的某一个

.字符可以匹配任意单个字符。在最后一个例子里,我们使用了.a来匹配na和sa。现在,如果在那份文件清单里增加了一个名为ca1.xls的文件,而你仍只想找出na和sa,你该怎么办?别忘了,.也能匹配c,所以文件名cal.xls也会被找出。

既然只想找出n和s,使用可以匹配任意字符的.显然不行——我们不需要匹配任意字符,我们只想匹配n和s这两个字符。在正则表达式里,我们可以使用元字符[和]来定义一个字符集合。在使用[和]定义的字符集合里,这两个元字符之间的所有字符都是该集合的组成部分,字符集合的匹配结果是能够与该集合里的任意一个成员相匹配的文本。

下面这个例子与第2章里的最后一个例子相似,但我们在这次的正则表达式里使用了一个字符集合:

文本:

sales1.xls orders3.xls sales2.xls sales3.xls apac1.xls europe2.xls na1.xls na2.xls sa1.xls ca1.xls

正则表达式:

[ns]a.\.xls

结果:

这里使用的正则表达式以[ns]开头;这个集合将匹配字符n或s(但不匹配字符c或其他字符)​。​[]不匹配任何字符,它们只负责定义一个字符集合。

接下来,正则表达式里的字符a将匹配一个a字符,.将匹配一个任意字符,\.将匹配.字符本身,xls将匹配字符串xls。从结果上看,这个模式只匹配了3个文件名,与我们的预期完全一致。

虽然结果正确,但模式[ns]a.\.xls并不是最正确的答案。如果那份文件清单里还有一个名为usa1.xls的文件,它也会被匹配出来。这里涉及了位置匹配问题,而我们将在后面对此做专题讨论。

字符集合在不需要区分字母大小写(或者是只须匹配某个特定部分)的搜索操作里比较常见。比如说:

文本:

The phrase "regular expression" is often abbreviated as RegEx or regex.

正则表达式:

[Rr]eg[Ee]x

结果:

这里使用的模式包含着两个字符集合:​[Rr]负责匹配字母R和r, [Ee]负责匹配字母E和e。这个模式可以匹配RegEx和regex,但不匹配REGEX。

如果你打算进行一次不需要区分字母大小写的匹配,不使用这个技巧也能达到目的。这种模式最适合用在从全局看需要区分字母大小写,但在某个局部不需要区分字母大小写的搜索操作里。

2、利用字符集合区间

我们再来仔细看看那个从一份文件清单里找出特定文件的例子。我们刚才使用的模式[ns]a.\.xls还存在着另外一个问题。如果那份文件清单里有一个名为sam.xls的文件,结果会怎样?显然,因为.可以匹配所有的字符而不是仅限于数字,所以文件sam.xls也会出现在匹配结果里。

这个问题可以用一个如下所示的字符集合来解决:

文本:

sales1.xls orders3.xls sales2.xls sales3.xls apac1.xls europe2.xls sam.xls na1.xls na2.xls sa1.xls ca1.xls

正则表达式:

[ns]a[0123456789]\.xls

结果:

在这个例子里,我们改用了另外一个模式,这个模式的匹配对象是:第1个字符必须是n或s,第2个字符必须是a,第3个字符可以是任何一个数字(因为我们使用了字符集合[0123456789]​)​。注意,文件名sam.xls没有出现在匹配结果里,这是因为m与我们给定的字符集合(10个数字)不相匹配。

在使用正则表达式的时候,会频繁地用到一些字符区间(09、AZ,等等)​。为了简化字符区间的定义,正则表达式提供了一个特殊的元字符——字符区间可以用-(连字符)来定义。

下面还是刚才那个例子,但我们这次使用了一个字符区间:

正则表达式:

[ns]a[0-9]\.xls

结果:

模式[0-9]的功能与[0123456789]完全等价,所以这次的匹配结果与刚才那个例子完全一样。

字符区间并不仅限于数字,以下这些都是合法的字符区间:

  • A-Z,匹配从A到Z的所有大写字母。
  • a-z,匹配从a到z的所有小写字母。
  • A-F,匹配从A到F的所有大写字母。
  • A-z,匹配从ASCII字符A到ASCII字符z的所有字母。这个模式一般不常用,因为它还包含着[和^等在ASCII字符表里排列在Z和a之间的字符。

字符区间的首、尾字符可以是ASCII字符表里的任意字符。但在实际工作中,最常用的字符区间还是数字字符区间和字母字符区间。

在定义一个字符区间的时候,一定要避免让这个区间的尾字符小于它的首字符(例如[3-1]​)​。这种区间是没有意义的,而且往往会让整个模式失效。

-(连字符)是一个特殊的元字符,作为元字符它只能用在[]之间。在字符集合以外的地方,-只是一个普通字符,只能与-本身相匹配。因此,在正则表达式里,-字符不需要被转义。

在同一个字符集合里可以给出多个字符区间。比如说,下面这个模式可以匹配任何一个字母(无论大小写)或数字,但除此以外的其他字符(既不是数字也不是字母的字符)都不匹配:

[A-Za-z0-9]

这个模式是下面这个字符集合的简写形式:

正如大家看到的那样,字符范围使得正则表达式的语法变得非常简明。

下面是另一个例子,这次要查找的是RGB值(用一个十六进制数字给出的红、绿、蓝三基色的组合值,计算机可以根据RGB值把有关的文字或图象显示为由这三种颜色按给定比例调和出来的色彩)​。在网页里,RGB值是以#000000(黑色)​、#FFFFFF(白色)​、#FF0000(红色)的形式给出的。RGB值用大写或小写字母给出均可,所以#FF00ff(品红色)也是合法的RGB值。下面就是这个例子:

文本:

<BODY BGCOLOR="#336633" TEXT="#FFFFFF" MARGINWIDTH="0" MARGINHEIGHT="0" TOPMARGIN="0" LEFTMARGIN="0">

正则表达式:

#[0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f]

结果:

这里使用的模式以普通字符#开头,随后是6个同样的[0-9A-Fa-f]字符集合。这将匹配一个由字符#开头,然后是6个数字或字母A到F(大小写均可)的字符串。

3、取非匹配

字符集合通常用来指定一组必须匹配其中之一的字符。但在某些场合,我们需要反过来做,给出一组不需要得到的字符。换句话说,除了那个字符集合里的字符,其他字符都可以匹配。

最先想到的办法是,用一个字符集合把你需要的字符一一列举出来,但如果只需要把一小部分字符排除在外的话,那么做既麻烦又容易有遗漏。其实这里有一个更简明的办法:用元字符^来表明你想对一个字符集合进行取非匹配——这与逻辑非运算很相似,只是这里的操作数是字符集合而已。

文本:

sales1.xls orders3.xls sales2.xls sales3.xls apac1.xls europe2.xls sam.xls na1.xls na2.xls sa1.xls ca1.xls

正则表达式:

[ns]a[^0-9]\.xls

结果:

这个例子里使用的模式与前面的例子里使用的模式刚好相反。前面[0-9]只匹配数字,而这里[^0-9]匹配的是任何不是数字的字符。也就是说,​[ns]a[^0-9]\.xls将匹配sam.xls,但不匹配na1.xls、na2.xls或sa1.xls。

^的效果将作用于给定字符集合里的所有字符或字符区间,而不是仅限于紧跟在^字符后面的那一个字符或字符区间。

返回列表