括号配对检测python123_【教程】详解Python正则表达式之: (?(id/name)yes-pattern|no-pattern) 条件性匹配...

Python 2.7的手册中,官方的解释为:(?(id/name)yes-pattern|no-pattern)Will try to match with yes-pattern if the group with given id or name exists, and with no-pattern if it doesn’t. no-pattern is optional and can be omitted. For example, () is a poor email matching pattern, which will match with '' as well as 'user@host.com', but not with '

New in version 2.4.

下面先来详细解释一下这段话的含义:

1.(?(id/name)yes-pattern|no-pattern) 的作用是:对于给出的id或者name,先尝试去匹配 yes-pattern部分的内容;

如果id或name条件不满足,则去匹配no-pattern部分的内容;

这句话听着还是很拗口的,或者说一下子还是很难懂的。至少我之前第一次,以及后来的很多次,看了之后,也一样没有完全搞懂。

后来经过一些实践,算是终于有所了解其中的含义了。

所以此处有必要,再详细解释一下:

此处的name或id,是针对(当前位置的)条件性匹配之前的,某个已经通过group去分组的内容

其中:

如果是有命名的分组,即named group,则对应的该分组就有对应的name,即此处所指的就是对应的name;

如果是无命名的分组,即unnamed group,则对应的该分组也有对应的分组的编号,称为group的number,也叫做id,对应的就是这里的id;

注:

相关内容,如果不了解,请先去看:

所以,搞清楚了这里的id或name,才好理解这段话。

接着解释就是,前面已经通过对应的group去匹配对应的内容了,对应的有group的id或name,

如果前面的group匹配成功,则此处,就执行yes-pattern的匹配;

如果前面group匹配不成功,即没有找到符合该的group内容,则就匹配no-pattern;

其中,yes-pattern和no-pattern,都是对应的,普通的正则表达式,用来匹配所需的内容。

此时,才算基本明白其所要说的含义了。

2.根据语法,很明显,如果存在no-pattern,则前面要有个竖杠’|’,用来分隔yes-pattern和no-pattern

如果此处,不想写,不需要写no-pattern,则也是可以的,也是可以省略掉的,对应的,也就不需要再写那个竖杠’|’了。

3.上面给出了一个例子:

()

此处,还是先来解释解释吧。

其可以分解为:(

(\w+@\w+(?:\.\w+)+):最外层的括号内是\w+@\w+(?:\.\w+)+,其又可以分为:\w+@\w+:\w+表示尽可能多的匹配字母数字下划线,中间是匹配@字符本身,所以就是希望匹配到xxx@xxx

(?:\.\w+)+:前面是括号括起来的一组,加号+表示尽可能多的匹配括号内的。看完下面解释就明白了,此处就是匹配尽可能多的.xxx的内容?:\.\w+:此处,是(?:xxx)形式,即一个非捕获组,匹配xxx的内容,此处即去匹配\.\w+,即一个点,然后是字母数字下划线,即.xxx的内容。很容易理解,此处就是希望匹配到.com之类的内容

(?(1)>) :此处,就是真正我们此处最关系的,选择性匹配了。参考本身的语法:(?(id/name)yes-pattern|no-pattern) ,此处中的1,就是对应id,即之前的第一个组,即(,就是此处的yes-pattern,而此处很明显,no-pattern是被省略了。所以没有’|’。所以,此处的含义就很清楚了,就是去匹配,如果最开始的编号为1的那个组,即(,如果前面没有

很显然,此处这种匹配规则,是很不严谨的,对于很多复杂的邮箱地址,没法匹配到。所以,此处才说是“poor email matching pattern”,即相对是一个不是那么好的email的匹配规则。

至此,终于把此处的内容解释完毕了。

但是,对于选择性匹配,还是没有很深刻的理解。

下面,就通过详细的代码,来更加深入的解释,选择性匹配,有什么用,以及如何用。

下面,就以之前给某人写的一个正则表达式为例,来说明,什么是条件性匹配。

先说,关于有些人不清楚,觉得选择性匹配,有何用。那么此处,就来举个例子,相对比较实用的例子:

希望去写一个匹配规则,匹配用于输入的数字,其中,输入的内容只能是数字,也可能有小数点,如果有小数点,则小数点后面,此处特意限制为最多2位。

针对如上的需求,就可以用到选择性匹配去实现了:

如下是详细的代码演示:#!/usr/bin/python

# -*- coding: utf-8 -*-

"""

【教程】详解Python正则表达式之: (?(id/name)yes-pattern|no-pattern) 条件性匹配

https://www.crifan.com/detailed_explanation_about_python_regular_express_yes_or_no_conditional_match

Version: 2012-11-17

Author: Crifan

"""

import re;

#需求:

#类似于检测(最多两位小数的)数字的合法性:

#所有的字符都是数字

#如果有小数点,那么小数点后面最多2位数字

testNumStrList = {

#合法的数字

'12.34',

'123.4',

'1234',

#非法的数字

'1.234',

'12.',

'12.ab',

'12.3a',

'123abc',

'123abc456',

}

for eachNumStr in testNumStrList:

#下面这个是不严谨的,会导致:

#1.234 -> 只会去判断234,所以检测出整数部分是234,无小数

#123.4 -> 只会去判断4,所以检测出整数部分是4,无小数

#123abc456 -> 只会去判断456,所以检测出整数部分是456,无小数

#foundValidNumStr = re.search("(?P\d+)(?P\.)?(?P(?(foundPoint)\d{1,2}))$", eachNumStr);

#下面这个也是不严谨的,会导致:

#1.234 -> 只去判断1.23,所以检测出整数是1,小数是23

#12. -> 只会去判断12,所以检测出整数是12,无小数

#123abc456 -> 只会去判断123,所以检测出整数是123,无小数

#12.ab -> 只会去判断12,所以检测出整数是12,无小数

#123abc -> 只会去判断123,所以检测出整数是123,无小数

#12.3a -> 只会去判断12.3,所以检测出整数是12,小数是3

#foundValidNumStr = re.search("^(?P\d+)(?P\.)?(?P(?(foundPoint)\d{1,2}))", eachNumStr);

#下面这个,更不严谨,会导致中间只要有数字,那么基本上都会去匹配到,和实际的期望,差距最大

#foundValidNumStr = re.search("(?P\d+)(?P\.)?(?P(?(foundPoint)\d{1,2}))", eachNumStr);

#下面这个才是正确的

foundValidNumStr = re.search("^(?P\d+)(?P\.)?(?P(?(foundPoint)\d{1,2}))$", eachNumStr);

#也可以写成下面这样:

#foundValidNumStr = re.search("^(?P\d+)(\.)?(?P(?(2)\d{1,2}))$", eachNumStr); #这个也是同样的效果

#print "foundValidNumStr=",foundValidNumStr;

if(foundValidNumStr):

integerPart = foundValidNumStr.group("integerPart");

decimalPart = foundValidNumStr.group("decimalPart");

print "eachNumStr=%s\tis valid numebr ^_^, integerPart=%s, decimalPart=%s"%(eachNumStr, integerPart, decimalPart);

else:

print "eachNumStr=%s\tis invalid number !!!"%(eachNumStr);

当然,对于上述的正则表达式,即使理解了,但是可能很多人还是对于,如何从无到有的去写出来,觉得无从下手,所以,可以再去参考这个帖子:

【总结】

通过上面的代码,我们就更加容易理解了,对应的,选择性匹配组,是如何实现的。

实际中,当有类似的情况时,我们就可以充分利用这个高级搜索规则,去轻松的匹配,获得我们所需的内容了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值