我在为多行匹配编译正确的正则表达式时遇到问题。有人能指出我做错了什么。我正在循环使用包含数百个条目的基本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')
答案 0 :(得分:10)
更新我刚刚注意到你获得结果的真正原因;在你的代码中:
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')
>>>
答案 1 :(得分:0)
有时,更简单的方法是不使用正则表达式。只是一个例子
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;