python多行regex

2024-04-28 03:53:07 发布

您现在位置:Python中文网/ 问答频道 /正文

为多行匹配编译正确的正则表达式时遇到问题。有人能指出我做错了什么吗。我正在循环浏览一个基本的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”,“)

但要找的是:
(“硬件以太网00:22:38:8f:1f:43”、“00:22:38:8f:1f:43”、“node20007.domain.com”)


Tags: 文件recomhost硬件domainconfmatch
2条回答

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

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模块。

现在回到最初的答案,讨论您应该使用的模式:

不需要多行;只需匹配空白即可。使用以下构建基块构建模式:

(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')
>>>

有时,更简单的方法是不使用regex。只是个例子

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;

相关问题 更多 >