【读书】正则指引-2-量词
多字符匹配的一般形式为什么需要量词?因为使用量词可以方便的匹配多个字符。以匹配邮政编码为例,其是由6位数字构成的字符串,比如201203。根据之前学习的知识,匹配这样的字符串需要使用正则表达式dddddd。而使用量词进行匹配则只需要写成d{6}。 量词可以表达不确定的长度,其通用形式是{m,n},其中m和n是两个数字,m是下限,n是上限(均是闭区间),m和n共同限定了之前的元素能够出现的次数。 d{m,n}表示所匹配的数字字符串长度,最短是m个字符,最长是n个字符。 如果不确定长度的上限,可以省略n值,只给出m值,例如d{m,},表示数字字符串的长度必须在m个字符之上。 量词限定的出现次数一般都有明确的下限,如果没有,则默认为0。 注:量词中的逗号之后绝不能有空格。
常用量词{m,n}是量词表达的通用形式,在正则表达式中还存在三个作为“量词简记法”的常用量词,如下表:
一些使用常用量词的例子:
上面给出用于匹配open tag的正则表达式,也能够匹配self-closing tag。以目前已学知识无法解决。 特殊元字符:点号一般文档都说,点号可以匹配“任意字符”,但事实是,点号可以匹配除换行符n之外的任意字符。如果非要匹配“任意字符”,有两种办法:在正则匹配时指定使用单行模式(目前不解释细节),在这种模式下,点号可以匹配换行符;或者使用之前说过的通配字符组[sS](也可以是[dD]或[wW])。点号的使用容易出现滥用,比如随意使用.*或.+。 例如,之前我们使用”[^”]*”匹配双引号字符串,而“图省事”的做法是”.*”。这种用法会出现意外,因为用”.*”匹配双引号字符串,不但可以匹配正常的双引号字符串”quoted string”,还可以匹配格式错误的字符串”quoted string” and another”。另外”.*”无法匹配有换行符的情况。 这个问题简答的讲,是因为所使用量词的类型导致。之前介绍过的量词都属于匹配优先量词(greedy quantifier,也称作贪婪量词)。这类量词的特点是,在拿不准是否要匹配的时候,优先尝试匹配,并记下这个状态,以备将来进行回溯(backtracking)。例如下图所示过程 匹配优先量词使用的常见场景:
忽略优先量词使用的常见场景:
目前已知的匹配优先量词和其对应的忽略优先量词如下表所示
匹配优先量词和忽略优先量词逐一对应,只是在对应的匹配优先量词之后添加?,两者限定的元素能出现的次数也一样,遇到不能匹配的情况同样需要回溯;唯一的区别在于,忽略优先量词会优先选择“忽略”,而匹配优先量词会优先选择“匹配”。另外,匹配优先量词只需要考虑自己限定的元素能够匹配即可,而忽略优先量词必须兼顾它所限定的元素和之后的元素,效率自然大大降低,当处理字符串很长时,尤为明显。 问题:C语言的两种注释方式,一种是在行末,以//开头;另一种可以跨多行,以/*开头,以*/结束。要匹配这两种注释,如何写正则表达式? 忽略优先量词在HTML页面解析中的应用:
注:因为tag是不区分大小写的,所以如果还希望匹配大小写的情况,则必须使用字符组,table写成[tT][aA][bB][lL][eE]。 在实际的HTML代码中,table、tr、td这三个元素经常是嵌套的,它们之间存在着包含关系。但是仅仅使用正则表达式匹配,并不能得到这种包含关系信息。换句话说,正则表达式只能进行纯粹的文本处理,单纯依靠它不能整理出层次结构;如果希望解析文本的同时构建层次结构信息,则必须将正则表达式配合程序代码一起使用。 转义之前介绍过元字符的转义,这里要介绍的是量词的转义。对于常用量词所使用的字符+、*、?来说,如果希望表示这三个字符本身,直接添加反斜线,变为+、*、?即可。但是在一般形式的量词{m,n}中,虽然具有特殊含义的字符不止一个,转义时却只需要给第一个{添加反斜线即可,也就是说,如果希望匹配字符串{m,n},则正则表达式必须写成{m,n}。 需要注意的是针对忽略优先量词的转义,因为其需要对两个量词全部转义。例如,如果要匹配字符串*?,正则表达式必须写作*?,而不是*?。 下表为各种量词的转义
总结本篇将《正则指引》的第二章内容进行了概括总结,下次讲解正则表达式中的括号。参考资料《正则指引》:余晟。(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |