Нежадное регулярное выражение Python для очистки XML
У меня есть файл "XML-файл", в котором есть некоторые нежелательные символы
<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>
Что я делаю неправильно?
РЕДАКТИРОВАТЬ: мотивация для этого вопроса была решена (см. Комментарии, у меня был случайный и в файле XML, который заставлял его не анализировать - он не имел ничего общего с символами, которые я хочу удалить). Тем не менее, мне все еще интересно, возможно ли регулярное выражение (и что случилось с моей попыткой), и поэтому я не удаляю вопрос.
2 ответа
Точка не соответствует символу новой строки, если вы не укажете re.DOTALL
флаг.
re.sub("</([a-zA-Z]+)>.*?<","</\\1><",text, flags=re.DOTALL)
должно работать нормально. (Если это не так, мой питон виноват, а не регулярное выражение. Пожалуйста, исправьте.)
Я думаю, что это хорошая практика, чтобы быть максимально точным при определении классов персонажей, которые должны повторяться. Это помогает предотвратить катастрофический откат назад. Поэтому я бы использовал [^<]*
вместо .*?
с добавленным бонусом, который теперь находит беспризорных персонажей после последнего тега. Это не нужно re.DOTALL
флаг больше, так как [^<]
соответствует линекам.
"</[^>]+?>[^<>]+?<"
в 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>'