Нежадное регулярное выражение Python для очистки XML - PullRequest
2 голосов
/ 06 октября 2011

У меня есть файл 'xml file', в котором есть нежелательные символы

<data>
  <tag>blar </tag><tagTwo> bo </tagTwo>
  some extra 
  characters not enclosed that I want to remove
  <anothertag>bbb</anothertag>
</data>

Я думал, что следующая не жадная замена удалит символы, которые не были должным образом заключены в <sometag></sometag>

re.sub("</([a-zA-Z]+)>.*?<","</\\1><",text)
            ^          ^ ^     ^      text is the xml txt.  
         remember tag, | |     put tag back without and reopen next tag
               read everything until the next '<' (non-gready) 

Это регулярное выражение, похоже, находит только положение, обозначенное [[]] в </tag>[[]]<tagTwo> Что я делаю не так?

EDIT: Мотивация для этого вопроса была решена (см. Комментарии, у меня был случайный файл в файле xml, который заставлял его не анализировать - он не имел ничего общего с символами, которые я хочу удалить). Однако мне все еще интересно, возможно ли регулярное выражение (и что было не так с моей попыткой), и поэтому я не удаляю вопрос.

Ответы [ 2 ]

3 голосов
/ 06 октября 2011

Точка не соответствует символу новой строки, если не указан флаг re.DOTALL.

re.sub("</([a-zA-Z]+)>.*?<","</\\1><",text, flags=re.DOTALL)

должно работать нормально.(Если это не так, мой питон виноват, а не в регулярном выражении. Пожалуйста, исправьте.)

Я думаю, что это хорошая практика - быть максимально точным при определении классов символов, которые должны повторяться.Это помогает предотвратить катастрофический откат .Поэтому я бы использовал [^<]* вместо .*? с дополнительным бонусом, который теперь находит беспризорных символов после последнего тега.Для этого больше не понадобится флаг re.DOTALL, поскольку [^<] соответствует символам новой строки.

1 голос
/ 06 октября 2011
 "</[^>]+?>[^<>]+?<" 

в ipython:

In [1]: a="<data>  <tag>blar </tag><tagTwo> bo </tagTwo>  some extra   characters not enclosed that I want to remove  <anothertag>bbb</anothertag></data>"

In [2]: import re

In [3]: re.sub( "(</[^>]+?>)[^<>]+?<" ,"\\1<",a)
Out[3]: '<data>  <tag>blar </tag><tagTwo> bo </tagTwo><anothertag>bbb</anothertag></data>'
...