Похоже, у вас есть две ошибки, каждая из которых приведет к неправильному использованию строк, начинающихся с пробела.
Первая ошибка в утверждении
line = regex.sub('', line.strip())
, который удаляет все начальные пробелы до , передавая строку методу sub()
. Таким образом, регулярное выражение никогда не видит никаких строк, начинающихся с пробела.
Чтобы исправить это, необходимо вызвать метод strip()
после того, как вызван метод sub()
:
line = regex.sub('', line).strip()
Обратите внимание, что вся причина strip()
заключается в том, что завершающие символы новой строки удаляются, устанавливая line
в пустую строку для строк, которые следует игнорировать. Для этого можно использовать простой тест, поскольку пустые строки являются ложными.
В качестве альтернативы этот вызов может быть опущен, и вместо этого регулярное выражение может быть изменено для удаления новых строк. (Это можно сделать, заменив все «конечные» .*
на [\s\S]*
.)
Вторая ошибка в вашем регулярном выражении, которое просто совпадает с первой частью пробела в строке, а не со всей строкой. Это приводит к тому, что метод sub()
существенно удаляет начальные пробелы!
Демо 1 ? 1
regex = re.compile(r'^(?:\s+|[;#$@].*)|.*IN\s+(?:MX|TXT|SRV|NS).*|.*\s+TXT.*|\s.+')
↑_↑
|
only matches the leading white-space part, not the whole line
Быстрое решение состоит в том, чтобы продвинуться вперед закрывающей скобки не захватывающей группы:
Демо 2 ? 1
regex = re.compile(r'^(?:\s+|[;#$@]).*|.*IN\s+(?:MX|TXT|SRV|NS).*|.*\s+TXT.*|\s.+')
↑ ↓
←
Обратите внимание, что более простое регулярное выражение можно создать, осознав, что метасимвол пробела \s
может быть перемещен внутри класса символов, и что нам нужно проверить только первый символ строки:
Демо 3 ? 1
regex = re.compile(r'^[\s;#$@].*|.*IN\s+(?:MX|TXT|SRV|NS).*|.*\s+TXT.*|\s.+')
Наконец, дальнейшее упрощение может быть достигнуто путем сопоставления каждой строки без пробелов, которая не является лидирующим пробелом и которая не указывает на запись CNAME или A, с использованием отрицательного взгляда, а не путем явного и исчерпывающего сопоставления. строки, которые указывают на записи не-CNAME / не-A:
Демо 4 ? 1
regex = re.compile(r'^(?:[\s;#$@]|(?!.*IN\s+[AC])).*|\s.+')
Или, если вы предпочитаете меньше вложенности (плюс на один символ короче ;-)):
Демо 5 ? 1
regex = re.compile(r'^[\s;#$@].*|^(?!.*IN\s+[AC]).*|\s.+')
Это полная рабочая версия вашего кода с использованием последнего регулярного выражения:
import re
regex = re.compile(r'^[\s;#$@].*|^(?!.*IN\s+[AC]).*|\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))
1 Все демонстрационные регулярные выражения были подправлены (последний метасимвол пробела \s
был заменен пробелом), чтобы можно было использовать многострочный флаг для отображения все полученные строки с выполненными заменами (в поле «ЗАМЕНА»). Это не влияет на функциональность регулярных выражений, так как тестовая строка содержит только пробелы и символы новой строки и никаких других пробелов.