我正在尝试解析 linux dig 的输出使用正则表达式一次命令并执行多项操作。
假设我挖掘了主机 mail.yahoo.com
:
/usr/bin/dig +nocomments +noquestion \
+noauthority +noadditional +nostats +nocmd \
mail.yahoo.com A
该命令输出:
mail.yahoo.com. 0 IN CNAME login.yahoo.com.
login.yahoo.com. 0 IN CNAME ats.login.lgg1.b.yahoo.com.
ats.login.lgg1.b.yahoo.com. 0 IN CNAME ats.member.g02.yahoodns.net.
ats.member.g02.yahoodns.net. 0 IN CNAME any-ats.member.a02.yahoodns.net.
any-ats.member.a02.yahoodns.net. 12 IN A 98.139.21.169
我想要找到所有 <host>
, <record_type>
和<resolved_name>
仅使用一个正则表达式没有最后一个句点的部分
对于这个特殊的例子,mail.yahoo.com
,那就是:
[
('mail.yahoo.com', 'CNAME', 'login.yahoo.com'),
('login.yahoo.com', 'CNAME', 'ats.login.lgg1.b.yahoo.com'),
('ats.login.lgg1.b.yahoo.com', 'CNAME', 'ats.member.g02.yahoodns.net'),
('ats.member.g02.yahoodns.net', 'CNAME', 'any-ats.member.a02.yahoodns.net'),
('any-ats.member.a02.yahoodns.net', 'A', '98.139.21.169'),
]
但事实证明dig
命令可能会在名称末尾显示句点:
mail.yahoo.com.
^ ^ ^
| | |
Good dot | |
| |
Good dot |
|
(!) Baaaad dot
做一个分割 dig
的正则表达式的输出并返回带有最后句点的名称相当简单:
regex = re.compile("^(\S+).+IN\s+([A-Z]+)\s+(\S+)\.*\s*$",re.MULTILINE)
但是打电话.findall
使用该正则表达式确实会返回主机中的最后一个句点,因为 \S+
也将匹配最后一个句点:
[
('mail.yahoo.com.', 'CNAME', 'login.yahoo.com.'),
('login.yahoo.com.', 'CNAME', 'ats.login.lgg1.b.yahoo.com.'),
('ats.login.lgg1.b.yahoo.com.', 'CNAME', 'ats.member.g02.yahoodns.net.'),
('ats.member.g02.yahoodns.net.', 'CNAME', 'any-ats.member.a02.yahoodns.net.'),
('any-ats.member.a02.yahoodns.net.', 'A', '98.139.21.169'),
]
所以我需要匹配所有非空格的东西 \S
除非它是句点后跟空格。
我做了无数次尝试,但一直没能想出一个像样的解决方案。
提前谢谢您!
PS: 我知道我总是可以使用“简单”正则表达式并(在第二次传递时)删除找到的字符串的最后一个点,但我很好奇是否可以使用正则表达式一次性完成此操作。
最佳答案
您可以简单地强制组末尾没有句点(并且不包含空格):
npg = '([^\.\s]+(?:.[^\.\s]+)*)' #not_period_ending_group
regex = re.compile("^" + npg + ".+IN\s+([A-Z]+)\s+" + npg +".+$",re.MULTILINE)
关于python - 正则表达式 : Remove last period in string that can contain other periods (dig output),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26497803/