Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从DNS区域文件提取源域的脚本没有跳过带前导空格的行_Python_Regex - Fatal编程技术网

Python 从DNS区域文件提取源域的脚本没有跳过带前导空格的行

Python 从DNS区域文件提取源域的脚本没有跳过带前导空格的行,python,regex,Python,Regex,我希望清理我们的DNS区域文件,以便提取只包含CNAME和A记录的源域,并删除所有注释、TXT、MX和SRV记录。最重要的是,我想自动化这个过程 我已经成功地创建了一个正则表达式,它可以用来在崇高的文本中执行查找和替换,并且需要几次迭代才能达到所需的结果 让我们以以下示例DNS区域文件为例: $ORIGIN example.com。 @3600 SOA ns1.p30.dynect.net。( zone-admin.dyndns.com;责任方地址 2016072701;序列号 NS ns1.p

我希望清理我们的DNS区域文件,以便提取只包含
CNAME
A
记录的源域,并删除所有注释、
TXT
MX
SRV
记录。最重要的是,我想自动化这个过程

我已经成功地创建了一个正则表达式,它可以用来在崇高的文本中执行查找和替换,并且需要几次迭代才能达到所需的结果

让我们以以下示例DNS区域文件为例:

$ORIGIN example.com。
@3600 SOA ns1.p30.dynect.net。(
zone-admin.dyndns.com;责任方地址
2016072701;序列号
NS ns1.p30.dynect.net中的86400。
MX 10 mail.example.com中的3600。
A 204.13.248.106中的60
abc TXT“v=spf1 includespf.dynect.net~all”
邮寄至204.13.248.106
TXT中的vpn v=spf1 includespf.dynect.net~all“
MX中的vpn2 v=spf1 includespf.dynect.net~all“
216.146.46.10中的webapp
#A 216.146.46.10中的webapp1
CNAME example.com中的xyz。
SRV 216.146.46.11中的webapp
;A 216.146.46.11中的webapp2
第一步

将此用于“查找”

什么都没有取代

这将清理区域文件并仅显示指向
CNAME
A
记录的源域

步骤2

将以下内容用于“查找”

并将其替换为

\1.example.com
结果是一个源域列表,附加了源域:

mail.example.com
webapp.example.com
xyz.example.com

我现在正试图编写一个Python脚本,对给定的区域文件执行上述操作,并将其输出到
.txt
文件

Stack Overflow的一位正则表达式和Python专家帮助我编写了以下内容:

import re

regex = re.compile(r'^(?:\s+|[;#$@].*)|.*IN\s+(?:MX|TXT|SRV|NS).*|.*\s+TXT.*|\s.+')
with open('1.txt', 'r',encoding='UTF8') as dns:
    with open('2.txt', 'w',encoding='UTF8') as output:
        for line in dns:
            if line.strip():
                line = regex.sub('', line.strip())
                if line:
                    output.write("{}.example.com\n".format(line))
不幸的是,脚本的输出如下:

zone admin.dyndns.com..example.com
2016072701.example.com
60.example.com
mail.example.com
webapp.example.com
xyz.example.com

脚本没有忽略以空格开头的行。我做错了什么?

看起来您有两个错误,每个错误都会导致错误使用以空格开头的行


第一个错误在语句中

line = regex.sub('', line.strip())
它在将行传递给
sub()
方法之前去掉任何前导空格。因此正则表达式从未看到任何以空格开头的行

要解决此问题,需要在调用
sub()
方法后调用
strip()
方法:

line = regex.sub('', line).strip()
请注意,
strip()
的全部原因是删除尾随的换行符,将要忽略的行的
line
设置为空字符串。可以使用一个简单的测试来检查这一点,因为空字符串是错误的

作为替代,可以省略此调用,而可以修改正则表达式以删除换行符。(这可以通过将所有“尾部”
*
替换为
[\s\s]*
来完成。)


第二个错误在正则表达式中,它只匹配行的前导空格部分,而不是整个行。这会导致
sub()
方法从本质上去除前导空格!

Demo 1非常感谢。不幸的是,输出没有如预期的那样。我相信代码正在通过附加替换与CNAME或记录不匹配的每一行。example.com请使用上面的DNS文件内容作为输入文件,并尝试运行您的代码。您将知道我在说什么。@DataShark啊,是的,这非常有效!再次感谢n、 此外,我还添加了以下代码
uniqlines=set(open('2.txt').readlines())bar=open('2.txt','w').writelines(sorted(set(uniqlines)))
,该代码将删除重复项并对唯一行进行排序。
line = regex.sub('', line.strip())
line = regex.sub('', line).strip()