正则表达式——概述和入门
概述和入门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亦或其他字符。如前所述点号一般不匹配行起始符比如换行符U000A。然而有很多方法可以使点号匹配行起始符之后我会展示。这通常叫做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}是表示匹配四位数字的量词美元符$匹配行结束位置。这个表达式最终匹配十位的北美电话号码而且括号、连字符或者点号都是可选的。你可以试试不同格式的电话号码看看它能否匹配。