蟒蛇多行正则表达式

问题描述:

我遇到了编译多行匹配的正确正则表达式的问题。有人能指出我做错了什么吗?我通过一个基本的dhcpd.conf文件循环与数百个条目,如:蟒蛇多行正则表达式

host node20007                             
{                                
    hardware ethernet 00:22:38:8f:1f:43;                      
    fixed-address node20007.domain.com;  
} 

我已经得到了不同的正则表达式的为MAC和固定地址的工作,但不能将它们组合起来,以正确地匹配。

f = open('/etc/dhcp3/dhcpd.conf', 'r') 
re_hostinfo = re.compile(r'(hardware ethernet (.*))\;(?:\n|\r|\r\n?)(.*)',re.MULTILINE) 

for host in f: 
match = re_hostinfo.search(host) 
    if match: 
     print match.groups() 

目前我比赛团体看起来像:
( '硬件以太网00:22:38:8F:1F:43','00:22:38:8F:1F:43' , '' )

但是寻找类似于:
('hardware ethernet 00:22:38:8f:1f:43','00:22:38:8f:1f:43','node20007.domain.com ')

+1

http://www.pythonregex.com/ – nmichaels 2011-01-19 21:08:13

+0

如果文件正是这种形式可能更容易哟刚在空格上分割线条并将最后的元素作为值 – Mark 2011-01-19 21:10:14

更新我刚刚注意到你得到结果的真正原因,在你的代码:

for host in f: 
    match = re_hostinfo.search(host) 
    if match: 
     print match.groups() 

host指的是单线,但你的模式需要在两行工作。

试试这个:

data = f.read() 
for x in regex.finditer(data): 
    process(x.groups()) 

其中regex是编译的模式,超过两行相匹配。

如果您的文件很大,并且您确定感兴趣的部分总是分布在两行中,那么您可以一次读取一行文件,检查该行的第一部分模式,设置一个标志告诉你下一行是否应该检查第二部分。如果您不确定,它会变得越来越复杂,或许足以开始查看pyparsing模块。

现在回到原来的答案,讨论模式,你应该使用:

你不需要MULTILINE;只是匹配空白。使用这些构建模块建立你的模式:

(1)固定文字 (2)一个或多个空格字符 (3)一个或多个非空白字符

,然后放在括号中,让您的组。

试试这个:

>>> m = re.search(r'(hardware ethernet\s+(\S+));\s+\S+\s+(\S+);', data) 
>>> print m.groups() 
('hardware ethernet 00:22:38:8f:1f:43', '00:22:38:8f:1f:43', 'node20007.domain.com') 
>>> 

请考虑使用“详细模式” ......你可以用它来记录完全相同,其中 模式匹配块的数据块,它往往可以帮助获取模式首先是正确的。例如:

>>> regex = re.compile(r""" 
... (hardware[ ]ethernet \s+ 
...  (\S+) # MAC 
...) ; 
... \s+ # includes newline 
... \S+ # variable(??) text e.g. "fixed-address" 
... \s+ 
... (\S+) # e.g. "node20007.domain.com" 
... ; 
... """, re.VERBOSE) 
>>> print regex.search(data).groups() 
('hardware ethernet 00:22:38:8f:1f:43', '00:22:38:8f:1f:43', 'node20007.domain.com') 
>>> 
+0

非常感谢。谢谢。 – Joshua 2011-01-20 23:42:12

有时,更简单的方法是不使用正则表达式。只是一个例子

for line in open("dhcpd.conf"): 
    line = line.rstrip() 
    sline = line.split() 
    if "hardware ethernet" or "fixed-address" in line: 
     print sline[-1] 

另一种方式

data = open("file").read().split("}"); 
for item in data: 
    item = [ i.strip() for i in item.split("\n") if i != '' ]; 
    for elem in item: 
     if "hardware ethernet" in elem: 
      print elem.split()[-1] 
    if item: print item[-1] 

输出

$ more file 
host node20007 
{ 
    hardware ethernet 00:22:38:8f:1f:43; 
     fixed-address node20007.domain.com; 
} 

host node20008 
{ 
    hardware ethernet 00:22:38:8f:1f:44; 
     some-address node20008.domain.com; 
} 

$ python test.py 
00:22:38:8f:1f:43; 
fixed-address node20007.domain.com; 
00:22:38:8f:1f:44; 
some-address node20008.domain.com;