如何从python中的一行中捕获多个模式?

时间:2016-01-14 15:58:27

标签: python regex

数据如下:

text textext text a 111.222.222.111(123) -> 22.222.111.111(7895)
txt txt txxt text b 22.111.22.222(8153) -> 153.33.233.111(195)
text text txt txt c 222.30.233.121 -> 44.233.111.111
txt text txt text d 22.111.22.222 -> 153.33.233.111

我想捕获a,b和c以及该行上的两个IP。我不希望括号中的数字附加到某些IP上。

我希望我的输出看起来像这样:

a 111.222.222.111 22.222.111.111
b 22.111.22.222 153.33.233.111
c 222.30.233.121 44.233.111.111

代码是什么样的:

f=gzip.open(path+Fname,'rb')
for line in f:
    IP_info=re.findall( r'(a|b|c)\s+([0-9]+(?:\.[0-9]+){3})+[ -> ]+([0-9]+(?:\.[0-9]+){3})', line )
    print IP_info
f.flose

我的出局实际上是什么样的:

[('a', '111.222.222.111', '2.222.111.111')]
[('b',  '22.111.22.222', '3.33.233.111')]

我遇到的两个最大问题是:

1)输出中的第二个IP未完成。前两位数字已被截断。

2)我没有捕获“c”的信息。

1 个答案:

答案 0 :(得分:2)

以下是您可以使用的正则表达式:

\b([abcd])\s+([0-9]+(?:\.[0-9]+){3})(?:\(\d+\))? +-> +([0-9]+(?:\.[0-9]+){3})

请参阅regex demo

这里有几点感兴趣:

  • 我将[ -> ]+替换为+-> +,因为您打算匹配字符的序列,而不仅仅是单个字符的各种顺序。 请注意,字符类中的->创建了一个范围,从空格到>,其中包括特殊符号,标点符号和数字。这就是为什么你的IP被部分“吃掉”的原因。
  • 由于IP后括号中有可选数字,我在第一个IP之后添加了一个可选的非捕获组(?:\(\d+\))?
  • 你在第一个捕获组中没有匹配d(我转换成一个字符类,因为我只看到一个字母 - 如果这些是“占位符”,请回复到一个有替代的组 - {{1 }})。

请参阅Python demo

(a|b|c|d)

输出:

import re
p = re.compile(r'\b([abcd])\s+([0-9]+(?:\.[0-9]+){3})(?:\(\d+\))? +-> +([0-9]+(?:\.[0-9]+){3})')
test_str = "text textext text a 111.222.222.111(123) -> 22.222.111.111(7895)\ntxt txt txxt text b 22.111.22.222(8153) -> 153.33.233.111(195)\ntext text txt txt c 222.30.233.121 -> 44.233.111.111\ntxt text txt text d 22.111.22.222 -> 153.33.233.111"
for x in test_str.split("\n"):
    print(re.findall(p, x))