lengyudu 发表于 2016-6-12 17:16:45

57课正则表达式实践中的问题

看了教学视频中取IP地址代码是
re.search(r'(({0,1}\d{0,1}\d|2\d|25)\.){3}({0,1}\d{0,1}\d|2\d|25)', '192.168.1.1')

虽然可以成功取得IP,但是这个代码如果一边写一边测试就会发现有问题,如果只取IP地址的第一段(不加点),那么{0,1}\d{0,1}\d|2\d|25,这段代码如果取200以上的数值就会出现问题,只能取3位当中的前两位,举例234,只能取到23.换句话说 ,视频中的例子 如果取234.234.234.234,那么只能得到234.234.234.23.
我发现如果调换这个匹配条件是可以解决的我的代码如下
re.search(r'((25|2\d|?\d?\d)\.){3}(25|2\d|?\d?\d)', '234.234.234.234')是可以的.
但是造成这种情况的原因我还是不太明白.

bajisuan 发表于 2016-8-15 19:45:28

我认为应该是因为|位于前面的优先。
re.search(r'(({0,1}\d{0,1}\d|2\d|25)\.){3}({0,1}\d{0,1}\d|2\d|25)', '234.234.234.234')中,最后一段{0,1}\d{0,1}\d优先于25导致{0,1}\d{0,1}\d取了23,
得到的结果就是234.234.234.23。

而至于为什么前面为什么不是23而是234,是因为前面的格式必须符合"x."
假如是"{0,1}\d{0,1}\d"优先取23了,那么23后面必须紧跟".",但是23后面还有个4,导致"{0,1}\d{0,1}"\d不符合规则,所以紧接着符合规则的"25)\"优先。

SixPy 发表于 2016-8-16 08:11:52

bajisuan 发表于 2016-8-15 19:45
我认为应该是因为|位于前面的优先。
re.search(r'(({0,1}\d{0,1}\d|2\d|25)\.){3}({0,1 ...

python的 正则表达式中 | 表示 或 关系,和 python的 or 运算符相似,

例如
'A|B|C'
表示:
A or B or C

我们知道,or 运算符 是短路算法的,从左到右,如果A为 True,后面的B、C就不会进行计算。
正则表达式中 | 也是如此,如果A匹配后,B、C则不会进行测试。

--------------------

严谨一点的写法,如下:
import re
ptnIP = re.compile(r'(?<![\d.])' # 前导 无 数字和小数点
                   r'(?:(?:'
                   r'?\d?\d' #   0 ~ 199
                   r'|2\d'# 200 ~ 249
                   r'|25)'# 250 ~ 255
                   r'\.){3}'   # 3组 xxx.
                   r'(?:'
                   r'?\d?\d'
                   r'|2\d'
                   r'|25)'
                   r'(?![\d.])'# 后续 无 数字和小数点
                  )
                  
strIP = ('0.0.0.0'
      ';1.22.333.444'
      ';2.0.0.256'
      ';3.22.33.23333333'
      ';4.2.3.4.5'
      ';5.111.222.99'
      ';6.0.0.0'
      ';7.234.234.234'
      ';255.255.255.255')
      
mch = ptnIP.findall(strIP)
print(mch)

战神貔貅 发表于 2020-8-6 17:24:23

代码看不懂,看的眼痛。理是这么个理。
页: [1]
查看完整版本: 57课正则表达式实践中的问题