python多线正则表达式

Jos*_*ua 5 python regex

我在为多行匹配编译正确的正则表达式时遇到问题.有人能指出我做错了什么.我循环遍历一个基本的dhcpd.conf文件,其中有数百个条目,例如:

host node20007                                                                                                                  
{                                                                                                                              
    hardware ethernet 00:22:38:8f:1f:43;                                                                                       
    fixed-address node20007.domain.com;     
}
Run Code Online (Sandbox Code Playgroud)

我已经获得了各种正则表达式来处理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()
Run Code Online (Sandbox Code Playgroud)

目前我的匹配组将如下所示:(
'hardware ethernet 00:22:38:8f:1f:43','00:22:38:8f:1f:43','')

但寻找类似的东西:(
'硬件以太网00:22:38:8f:1f:43','00:22:38:8f:1f:43','node20007.domain.com')

Joh*_*hin 10

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

for host in f:
    match = re_hostinfo.search(host)
    if match:
        print match.groups()
Run Code Online (Sandbox Code Playgroud)

host 是指单行,但您的模式需要在两行上工作.

试试这个:

data = f.read()
for x in regex.finditer(data):
    process(x.groups())
Run Code Online (Sandbox Code Playgroud)

哪个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')
>>>
Run Code Online (Sandbox Code Playgroud)

请考虑使用"详细模式"...您可以使用它来准确记录哪些模式匹配哪些数据,并且它通常可以帮助首先获得模式.例:

>>> 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')
>>>
Run Code Online (Sandbox Code Playgroud)