正则表达式——概述和入门
2026/8/5 23:58:10 网站建设 项目流程

概述和入门

    • 1、从Regexpal开始
    • 2、匹配北美电话号码
    • 3、用字符组来匹配数字
    • 4、使用字符组简写式
    • 5、匹配任意字符
    • 6、捕获分组和后向引用
    • 7、使用量词
    • 8、括选文字符

1、从Regexpal开始

首先介绍一下Regexpal网站(http://www.regexpal.com)​。在Google Chrome或者Mozilla Firefox之类的浏览器中打开该网站,可以看到如图所示的网站页面。

接近浏览器窗口的顶部有一个文本区,下方还有一个更大的文本区。顶部的文本区是用来输入正则表达式的,下方的文本区是用来输入主题或目标文本的。目标文本即要从中匹配字符串的文本。

2、匹配北美电话号码

现在我们要写一个正则表达式匹配北美电话号码。在Regexpal的下方文本框中键入以下电话号码:

707-827-7019

知道这是哪里的电话号码吗?这是O’Reilly Media的电话号码。

接下来用正则表达式匹配这个号码。有很多方法都可以做到,但首先只要在上方的文本框键入这个号码本身,也就是与下方文本框的内容完全一致即可(先忍耐一下,别泄气)​:

707-827-7019

这时,你应该看到下方文本框中的电话号码从头到尾都以黄色被高亮显示。如果你的结果也是这样(如图所示)​,那么一切正常。

刚刚你所写的正则表达式是用字符串字面值(stringliteral)来匹配目标字符串的。所谓字符串字面值,就是字面上看起来是什么就是什么。

现在将上方文本框的号码删除,然后只键入数字7。你看到什么了?现在只有数字7高亮显示。正则表达式中的字面值(数字)7与目标文本中数字7的四个实例匹配。

3、用字符组来匹配数字

如果想同时匹配电话号码中的所有数值或者只匹配特定的数值,该怎么办呢?

在上方的文本框中尝试以下表达式:

[0-9]

下方文本框中所有的数值(准确地说,应该是数字)以黄色和蓝色交替高亮显示。正则表达式[0-9]对正则表达式处理器传递的信息是“匹配0到9范围内的任意数字”​。

正则表达式将方括号视为特殊的元字符(metacharacter)​,因此方括号不参与匹配。元字符是在正则表达式中有特殊含义的字符,也是保留字符。​[0-9]这种形式的正则表达式称做字符组(character class)​,有时也叫字符集(character set)​。

可以对数字的范围进行进一步限定。用更具体的一组数字也能得到同样的结果,比如:

[012789]

这个字符组只会匹配列出的数字,即0、1、2、7、8、9。在上方的文本框中试一试,下方文本框中的相应数字同样会被交替标亮。

要匹配任意10位以连字符分隔的北美电话号码,可以使用以下正则表达式:

[0-9][0-9][0-9]-[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]


这是可以的,但太长了。更好的方法是采用简写形式。

4、使用字符组简写式

就像在本章开始看到的那样,\d可以像[0-9]一样匹配任意阿拉伯数字。请在上方文本框内试一试,和之前的表达式一样,下方的数字都被标亮了。这种正则表达式叫做字符组简写式(character shorthand)​,也叫转义字符(character escape)​。但后一种称谓很容易造成误解,我会尽量不用。至于原因,稍后我再解释。

可以使用以下表达式来匹配电话号码中的任意数字:

\d\d\d-\d\d\d-\d\d\d\d


重复\d三次和四次就可以分别匹配三个和四个数字。该表达式中的连字符是一个字面值,因此会被原样匹配。

除了和上面表达式一样,使用连字符本身(-)来匹配连字符之外,也可以用转义的大写D(\D)​,它匹配任何一个非数字字符。

以下示例使用了\D(而没有使用连字符本身)来匹配连字符:

\d\d\d\D\d\d\d\D\d\d\d\d


这次整个电话号码包括连字符又都被标亮了。

5、匹配任意字符

还可以用点号(.)来匹配那些讨厌的连字符:

\d\d\d.\d\d\d.\d\d\d\d


点号(英文句号)是一个通配符,可以匹配任意字符(但某些情况下不能匹配行起始符)​。以上示例中的正则表达式匹配了连字符,但它也可以匹配百分号(%)​:

707%827%7019


或者是竖线(|)​:

707|827|7019


亦或其他字符。

如前所述,点号一般不匹配行起始符,比如换行符(U+000A)​。然而,有很多方法可以使点号匹配行起始符,之后我会展示。这通常叫做dotall选项。

6、捕获分组和后向引用

本节我们使用捕获分组(capturing group)来匹配电话号码中的某一部分。然后使用后向引用(backreference)对分组中的内容进行引用。要创建捕获分组,先将一个\d放在一对圆括号中,这样就将它放入了一个分组中,后面可以用\1来对捕获的内容进行后向引用:

(\d)\d\1


\1对括号内分组捕获的内容进行了反向引用。这个正则表达式匹配的是区号707。以下是对该表达式的详细分析:

  • (\d)匹配第一个数字并将其捕获(数字7)​;
  • \d匹配第二个数字(数字0)但没有捕获,因为没有括号;
  • \1对捕获的数字进行反向引用(数字7)​。

现在可以用一个分组和几个后向引用对整个电话号码进行匹配:

(\d)0\1\D\d\d\1\D\1\d\d\d


但这还不够简洁美观。下一节我们会尝试更好的方法。

7、使用量词

现在用另一种语法来匹配电话号码:

\d{3}-?\d{3}-?\d{4}

花括号中的数字表示待查找的数字出现的次数。包含数字的花括号是一种量词(quantifier)​。花括号本身用做元字符。

问号是另一种量词,在以上表达式中表示连字符是可选的。也就是说,连字符可以不出现或只出现一次。还有其他的量词,例如加号(+)表示“一个或多个”​,星号()表示“零个或多个”​。

使用量词能让正则表达式变得更简洁:

(\d{3,4}[.-]?)+


对,加号表示出现一次或多次。这个正则表达式表示括号里的模式出现一次或多次,括号里的模式匹配三位或四位数字,后跟一个连字符或一个点号。

你有没有头晕呢?我希望没有。下面逐一解释表达式中的每一项:

  • 左圆括号(为捕获分组的起始符;
  • 反斜杠\为字符组简写式的起始符(对之后的字符进行转义)​;
  • 字符d为字符组简写式的结束符(d匹配0到9范围内的任意数字)​;
  • 左花括号{为量词起始符;
  • 数字3为匹配的最小数量;
  • 逗号隔开不同的数量;
  • 数字4为匹配的最大数量;
  • 右花括号}为量词的结束符;
  • 左方括号[为字符组的起始符;
  • 点号(匹配点号本身)​;
  • 连字符-匹配连字符的本身;
  • 右方括号]为字符组的结束符;
  • 问号?表示量词“零个或一个”​;
  • 右圆括号)为捕获分组的结束符;
  • 加号+表示量词“一个或多个”​。

这个表达式能用但不完全对,因为它只能匹配3位或4位的数字,而不管是否符合电话号码的格式。好吧,犯错会让我们印象深刻,进步得更快。

我们来改进一下:

(\d{3}[.-]?){2}\d{4}


这个表达式匹配的字符串是连续两个无括号的三位数字,每三位数字后可以带连字符也可以不带,最后是一个四位数字。

8、括选文字符

最后这个正则表达式表示第一个3位数字可以带也可以不带括号,即区号是可选的:

^(\(\d{3}\)|^\d{3}[.-]?)?\d{3}[.-]?\d{4}$


为了便于理解,我们再依次看一下表达式中的各项:

  • 出现在正则表达式起始位置或者竖线(|)之后的脱字符^,表示电话号码会出现在一行的起始位置;
  • 左括号(为捕获分组的起始符;
  • \(表示左括号本身;
  • \d匹配一位数字;
  • \d之后的{3}是量词,表示匹配三位数字;
  • \)匹配右括号本身;
  • 竖线符|表示选择,也就是从多个可选项中选择一个,换句话说,它表示“匹配一个不带括号的区号或一个带括号的区号”​;
  • 脱字符^匹配行起始位置;
  • \d匹配一位数字;
  • {3}是表示匹配三位数字的量词;
  • [.-]​?匹配一个可选的点号或连字符;
  • 右括号)为捕获分组的结束符;
  • 问号表示分组可选,即分组中的前缀可有可无;
  • \d匹配一位数字;
  • {3}表示匹配三位数字的量词;
  • [.-]​?匹配另一个可选的点号或连字符;
  • \d匹配一位数字;
  • {4}是表示匹配四位数字的量词;
  • 美元符$匹配行结束位置。

这个表达式最终匹配十位的北美电话号码,而且括号、连字符或者点号都是可选的。你可以试试不同格式的电话号码,看看它能否匹配。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询