正则表达式

253 阅读4分钟

定位符 ^$

目前我们关心的是整个字符串是否能由正则表达式匹配。但是,在默认情况下re.search(pattern,string)只判断string的某个子串能否由pattern匹配,即便pattern只能匹配string的一部分,也不会返回None。为了测试整个string能否由pattern匹配,在pattern两端加上^和。^和是正则表达式中的特殊字符,它们并不匹配任何字符,只是表示“定位到字符串的起始位置”和“定位到字符串的结束位置”(原理如图1-4所示,如果你现在就希望详细了解这两个特殊字符,可以参考第62页),这样就保证,只有在整个string都可以由pattern匹配时,才算匹配成功,不返回None,如例1-4所示。

范围表示

列出的麻烦,这样[0123456789]就可以表示为[0-9]。如果你觉得这么做看起来意义不大,那么[a-z]确实比[abcdefghijklmnopqrstuvwxyz]简单太多了。

字符组[0-9a-zA-Z]可以匹配数字、大写字母或小写字母;字符组[0-9a-fA-F]可以匹配数字,大、小写形式的a~f,它可以用来验证十六进制字符,

字符组[0-9a-zA-Z]可以匹配数字、大写字母或小写字母;字符组[0-9a-fA-F]可以匹配数字,大、小写形式的a~f,它可以用来验证十六进制字符,

转义

字符组[0-9a-zA-Z]可以匹配数字、大写字母或小写字母;字符组[0-9a-fA-F]可以匹配数字,大、小写形式的a~f,它可以用来验证十六进制字符,

排除型字符组

排除型字符组(Negated Character Class)非常类似普通字符组[…],只是在开方括号[之后紧跟一个脱字符^,写作[^…],表示“在当前位置,匹配一个没有列出的字符”。所以[^0-9]就表示“0~9之外的字符”,也就是“非数字字符”。那么,[^0-9][0-9]就可以解决问题了,如例1-13所示。

排除型字符组看起来很简单,不过新手常常会犯一个错误,就是把“在当前位置,匹配一个没有列出的字符”理解成“在当前位置不要匹配列出的字符”,两者其实是不同的,后者暗示“这里不出现任何字符也可以”。例1-14很清楚地说明:排除型字符组必须匹配一个字符,这点一定要记住。

在排除型字符组中,^是一个元字符,但只有它紧跟在[之后时才是元字符,如果想表示“这个字符组中可以出现^字符”,不要让它紧挨着[即可,否则就要转义。例1-16给出了三个正则表达式,后两个表达式实质是一样的,但第三种写法很麻烦,理解起来也麻烦,不推荐使用。

字符组简记

常见的字符组简记法有\d、\w、\s。从表面上看,它们与[…]完全没联系,但效果其实是等价的。其中\d等价于[0-9],其中的d代表“数字(digit)”;\w等价于[0-9a-zA-Z_],其中的w代表“单词字符(word)”;\s等价于[\t\r\n\v\f](第一个字符是空格),s表示“空白字符(space)”。例1-17说明了这几个字符组简记法的典型匹配。

字符运算

Java语言中提供了这样的字符组:[[a-z]&&[^aeiou]],虽然初看有点古怪,但仔细看看,也不难理解。[a-z]表示26个英文字母,[^aeiou]表示除元音字母之外的所有字符(还包括大写字母、数字和各种符号),两者取交集,就得到“26个英文字母中,除去5个元音字母,剩下的21个辅音字母”。

量词

常用量词

点号

有一个字符不能由点号匹配,就是换行符\n。这个字符平时看不见,却存在,而且在处理时并不能忽略(第3章会给出具体的例子)。

惰性量词

对[\s\S]来说,把改为*?就是使用了忽略优先量词,?限定的元素出现次数范围与完全一样,都表示“可能出现,也可能不出现,出现次数没有上限”。区别在于,在实际匹配过程中,遇到[\s\S]能匹配的字符,先尝试“忽略”,如果后面的元素(具体到这个表达式中,是)不能匹配,再尝试“匹配”,这样就保证了结果的正确性,

常见正则匹配

匹配 正则
双引号字符串 "[^"]" 或者 ".?"
匹配C语音/***/注释 /\*[\s\S]*?\*/
匹配超链接 <a\s[\s\S]+?</a>

unix 路径解析

量词字符串