正则表达式之常用量词

正则表达式之常用量词

{m,n}是通用形式的量词,正则表达式还有三个常用量词,分别是+?*。它们的形态虽然不同于{m,n},功能却是相同的(也可以把它们理解为“量词简记法”),具体说明见表2-2

 

2-2  常用量词

常用量词

{m,n}等价形式

说明

*

{0,}

可能出现,也可能不出现,出现次数没有上限

+

{1,}

至少出现1次,出现次数没有上限

?

{0,1}

至多出现1次,也可能不出现

 

在实际应用中,在很多情况只需要表示这三种意思,所以常用量词的使用频率要高于{m,n},下面分别说明。

大家都知道,美国英语和英国英语有些词的写法是不一样的,比如travelertraveller,如果希望“通吃”travelertraveller,就要求第2l是“至多出现1次,也可能不出现”的,正好使用?量词:travell?er,如例2-4所示。

 

2-4  量词?的应用

re.search(r"^travell?er$", "traveler") != None #  => True

re.search(r"^travell?er$", "traveller") != None     #  => True

 

其实这样的情况还有很多,比如favorfavourcolorcolour。此外还有很多其他应用场合,比如httphttps,虽然是两个概念,但都是协议名,可以用https?匹配;再比如表示价格的字符串,有可能是100也有可能是100,可以用?100匹配。

量词也广泛应用于解析HTML代码。HTML是一种“标签语言”,它包含各种各样的tag(标签),比如

等,这些 tag的名字各异,形式却相同:从 <开始,到>结束,在<>之间有若干字符,“若干”的意思是长度不确定,但不能为 0 <>并不是合法的 tag),也不能是 >字符。如果要用一个正则表达式匹配所有的 tag,需要用<匹配开头的 <,用 >匹配结尾的 >,用 [^>]+匹配中间的“若干字符”,所以整个正则表达式就是]+>,程序如例2-5所示。

 

2-5  量词+的应用

re.search(r"^]+>$", "") != None      #  => True

re.search(r"^]+>$", "

") != None         #  => True

re.search(r"^]+>$", "<>") != None           #  => False

 

类似的,也可以使用正则表达式匹配双引号字符串。不同的是,双引号字符串的两个双引号之间可以没有任何字符,""也是一个完全合法的双引号字符串,应该使用量词*,于是整个正则表达式就成了"[^"]*",程序见例2-6

 

2-6  量词*的应用

re.search(r"^\"[^\"]*\"$", "\"some\"") != None #  => True

re.search(r"^\"[^\"]*\"$", "\"\"") != None          #  => True

注:字符串之中表示双引号需要转义写成\",这并不是正则表达式中的规定,而是为字符串转义考虑。

 

量词的使用有很多学问,不妨多看几个tag匹配的例子:tag可以粗略分为open tagclose tag,比如就是open tag,而就是close tag;另外还有一类标签是self-closing tag,比如
。现在来看分别匹配这三类
tag的正则表达式。

open tag的特点是以<开头,然后是“若干字符”(但不能以/开头),最后是>,所以对应的正则表达式是]*>;注意:因为[^/]必须匹配一个字符,所以“若干字符”中其他部分必须写成[^>]*,否则它无法匹配名字为单个字符的标签,比如

close tag的特点是以<开头,之后是/字符,然后是“若干字符(但不能以/开头)”,最后是>,所以对应的正则表达式是[^>]+>

self-closing tag的特点是以<开头,中间是“若干字符”,最后是/>,所以对应的正则表达式是]+/>。注意:这里不是/]+/>,排除型字符组只排除>,而不排除/,因为要确认的只是在结尾的>之前出现/,如果写成/]+/>,则要求tag内部不能出现/,就无法匹配span"http://somehost/picture" />这类的tag了。

2-3列出了匹配几类tag的表达式。

 

2-3  各类tag的匹配

匹配所有tag的表达式

tag分类

匹配分类tag的表达式

 

]+>

open tag

][^>]*>

close tag

[^>]+>

self-closing tag

/]+/>

 

对比表格中“匹配所有tag的表达式”和“匹配分类tag的表达式”,可以发现它们的模式是相近的,只是细节上有差异。也就是说,通过变换字符组和量词,可以准确控制正则表达式能匹配的字符串的范围,达到不同的目的。这其实是使用正则表达式时的一条根本规律:使用合适的结构(包括字符组和量词),精确表达自己的意图,界定能匹配的文本。

再仔细观察,你或许会发现,匹配open tag的表达式,也可以匹配self-closing tag]*>能够匹配
,因为
[^>]*并不排除对/的匹配。那么将表达式改为]*[^/]>,就保证匹配的open tag不会以/>结尾了。

不过这会产生新的问题:]*[^/]>能匹配的tag,在<>之间出现了两个[^/],上一章已经讲过,排除型字符组表示“在当前位置,匹配一个没有列出的字符”,所以tag里的字符串必须至少包含两个字符,这样就无法匹配了。

仔细想想,真正要表达的意思是,在tag内部的字符串不能以/开头,也不能以/结尾,如果这个字符串只包含一个字符,那么它既是开头,又是结尾,使用两个排除型字符组显然是不合适的,看起来没办法解决了。实际上,只是现有的知识还不足够解决这个问题而已,在第68页有这个问题的详细解法。

 

 bb

本文节选自《正则指引》一书 余晟著

图书详细信息:http://space.itpub.net/?uid-13164110-action-viewspace-itemid-729855

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/13164110/viewspace-730037/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/13164110/viewspace-730037/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值