Удалить многострочный шаблон со специальными символами из файла - PullRequest
0 голосов
/ 15 апреля 2019

Мне нужно удалить многострочный шаблон из файла. Например:

  <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> ?> 

Я хотел бы удалить весь раздел, а не только частичную первую строку.

Ответы [ 4 ]

1 голос
/ 15 апреля 2019

Вы можете удалить многострочные шаблоны, используя этот шаблон <\?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
1 голос
/ 15 апреля 2019

Вы можете либо сделать точку совпадающей с новой строкой, используя, например, модификатор (?s), и экранировать знак вопроса \?, чтобы буквально соответствовать ей. Вы могли бы также сделать подход к началу точки не жадным .*?

(?s)<\?ignore.*?\?>

Regex demo | Python demo

Или вы можете использовать повторяющийся шаблон, чтобы сопоставить строку, которая не содержит ?>, используя отрицательный прогноз:

<\?ignore\b.*\n(?!.*\?>)(?:.*\n)*.*\?>
  • <\?ignore\b.*\n Совпадение <?ignore с последующим более чем 1 раз любым символом, за которым следует символ новой строки
  • (?!.*\?>) Отрицательный взгляд, утверждаю, что справа нет ?>
  • (?:.*\n)* Повторите 0+ раз, сопоставляя любой символ, кроме новой строки, за которой следует новая строка
  • .*\?> Совпадение 0+ раз с любым символом и ?>

Regex demo | Python demo

0 голосов
/ 15 апреля 2019

Это потому что?влияет на «жадные» квантификаторы: * и + таким образом, что делает их «ленивыми» - * и + начинают искать первое вхождение символа / группы после них и затем сопоставляют, возвращают.Итак, чтобы заставить ваше регулярное выражение работать, вам просто нужно сбежать?символ с \

<?ignore.*\?> будет работать, как вы ожидаете.

0 голосов
/ 15 апреля 2019

? является необязательным квантификатором в регулярном выражении, поэтому a? означает, что символ a является необязательным. Чтобы буквально обнаружить этот символ, вам нужно убежать от него.

попробуйте с

<\?ignore.*\?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...