#python #regex #python-3.x
#python #регулярное выражение #python-3.x
Вопрос:
Мне нужно удалить многострочный шаблон из файла. Например:
<Command name="somecom" type="type" >
<input name="some input" />
<output name="some output" />
</Command>
<?ignore <Command name="somecom" type="type" >
<input name="some input" />
<output name="some output" />
</Command> ?>
Раздел для удаления начинается с:
<?ignore
Заканчивается:
?>
Для этого я хочу использовать регулярное выражение. python3.6.3
with open('graph.xml', 'r') as readXML:
tempFile = readXML.read()
patr = re.compile("<?ignore.*?>", re.MULTILINE)
tempFile = re.sub(patr,"",tempFile)
print(tempFile)
Результат:
<Command name="somecom" type="type" >
<input name="some input" />
<output name="some output" />
</Command>
<?
<input name="some input" />
<output name="some output" />
</Command> ?>
Я бы хотел, чтобы был удален весь раздел, а не только частичная первая строка.
Ответ №1:
Вы можете удалить многострочные шаблоны, используя этот шаблон <?ignore. ??>
:
Пример:
import re
str = """
<Command name="somecom" type="type" >
<input name="some input" />
<output name="some output" />
</Command>
<?ignore <Command name="somecom" type="type" >
<input name="some input" />
<output name="some output" />
</Command> ?>
"""
print(re.sub(r'<?ignore. ??>', '', str, flags=re.MULTILINE|re.DOTALL))
Это выводит:
<Command name="somecom" type="type" >
<input name="some input" />
<output name="some output" />
</Command>
Не забудьте использовать флаги, иначе замена не будет работать:
flags=re.MULTILINE|re.DOTALL
Ответ №2:
Вы можете либо сделать так, чтобы точка соответствовала новой строке, используя, например, модификатор (?s)
, и избежать вопросительного знака ?
, чтобы соответствовать ему буквально. Вы также можете сделать подход к началу точки не жадным .*?
(?s)<?ignore.*??>
Демонстрация регулярных выражений | Демонстрация Python
Или вы можете использовать повторяющийся шаблон для сопоставления строки, которая не содержит ?>
, используя отрицательный прогноз:
<?ignoreb.*n(?!.*?>)(?:.*n)*.*?>
<?ignoreb.*n
Сопоставление<?ignore
, за которым следует 1 раз любой символ, за которым следует новая строка(?!.*?>)
Отрицательный прогноз, утверждать, что справа нет?>
(?:.*n)*
Повторите 0 раз, сопоставляя любой символ, кроме новой строки, за которой следует новая строка.*?>
Сопоставьте 0 раз любой символ и?>
Комментарии:
1. Большое спасибо за подробный ответ! Я использовал версию flags, поскольку она более дружелюбна, чем модификатор (?s)
Ответ №3:
?
является необязательным квантификатором в регулярном выражении, так что a?
это означает, что символ a
является необязательным. Чтобы обнаружить этот символ, вам нужно его экранировать.
попробуйте с
<?ignore.*?>
Ответ №4:
Это потому, что? влияет на «жадные» кванторы: * и таким образом, что делает их «ленивыми» — * и начинают искать первое появление символа / группы после них, а затем сопоставляют, возвращают. Итак, чтобы заставить ваше регулярное выражение работать, вам просто нужно escape? символ с
<?ignore.*?>
будет работать так, как вы ожидаете.