Python 正则:前后界定和前后非界定

在用正则去匹配识别手机号、QQ、微信号的时候,往往由于输入的文本可能非常的另类,比如,没有标点和隔断,这时`^`和`$`就用不上了。

不用其实也可以识别的,但是有个问题,手机后是11位数字,QQ是5~11或者更多数字,有可能从手机号中破坏性的匹配到QQ号。当然,此一类问题前后界定和前后非界定都适用。

前后界定和前后非界定中的界定的意思是:边界字符限制必须是或必须不能是的意思。

官方说法:

(?=pattern) 零宽正向先行断言(zero-width positive lookahead assertion) :代表字符串中的一个位置,紧接该位置之后的字符序列能够匹配pattern。
(?!pattern) 零宽负向先行断言(zero-width negative lookahead assertion) :代表字符串中的一个位置,紧接该位置之后的字符序列不能匹配pattern。 
(?<=pattern) 零宽正向后行断言(zero-width positive lookbehind assertion) :代表字符串中的一个位置,紧接该位置之前的字符序列能够匹配pattern。 
(?<!pattern) 零宽负向后行断言(zero-width negative lookbehind assertion) :代表字符串中的一个位置,紧接该位置之前的字符序列不能匹配pattern。 

为了说明问题,假设QQ是最长10位,最少5位的数字:

1 >>> import re
2 >>> cont = "小强的手机号是15877966552"
3 >>> print re.findall(r"[1-9]\d{4,9}",cont)
4 ['1587796655']

结果,正则从手机号中匹配到了结果,这是不对滴。有了前后非界定就好了:

1 >>> print re.findall(r"[1-9]\d{4,9}(?!\d)",cont)
2 []

再例如,文本中出现了成对的符号或字符,但实际上需要的是其内的部分,就用到了前后界定了:

1 >>> cont = "str = '小强的手机号是15877966552'"
2 >>> print re.findall(r"(?=\').*(?=\')",cont)
3 ['\xe5\xb0\x8f\xe5\xbc\xba\xe7\x9a\x84\xe6\x89\x8b\xe6\x9c\xba\xe5\x8f\xb7\xe6\x98\xaf15877966552']

因此,`^`和`$`是包含某字符的匹配,前后界定和前后非界定是不包含某字符的匹配,明白后以便见方抓药。

前行符`<`的作用,就是字面上向前(向左查找),默认为向后(向右查找)。还是上面的字符匹配手机号: 

1 >>> print re.findall(r"(?<=\D)1\d{10}(?!\d)",cont)
2 ['15877966552']
3 >>> print re.findall(r"(?<!\d)1\d{10}(?!\d)",cont)
4 ['15877966552']

参考:正则表达式的先行断言(lookahead)和后行断言(lookbehind)

转载于:https://www.cnblogs.com/yamboo/p/10772590.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值