Регулярное выражение для соответствия каждому символу новой строки (\n) внутри тега <content>
Я ищу регулярное выражение, чтобы соответствовать каждому символу новой строки (\n
) внутри тега XML, который <content>
или внутри любого тега, который находится внутри этого <content>
тег, например:
<blog>
<text>
(Do NOT match new lines here)
</text>
<content>
(DO match new lines here)
<p>
(Do match new lines here)
</p>
</content>
(Do NOT match new lines here)
<content>
(DO match new lines here)
</content>
2 ответа
На самом деле... вы не можете использовать простое регулярное выражение здесь, по крайней мере, не один. Вам, вероятно, нужно беспокоиться о комментариях! Кто-то может написать:
<!-- <content> blah </content> -->
Вы можете использовать два подхода здесь:
- Сначала удалите все комментарии. Затем используйте подход регулярных выражений.
- Не используйте регулярные выражения и используйте контекстно-зависимый подход к анализу, который может отслеживать, вложены ли вы в комментарии или нет.
Быть осторожен.
Я также не уверен, что вы можете сопоставить все новые строки сразу. @Quartz предложил это:
<content>([^\n]*\n+)+</content>
Это будет соответствовать любым тегам содержимого, которые имеют символ новой строки ПРАВО ПЕРЕД закрывающим тегом... но я не уверен, что вы подразумеваете под соответствием всем символам новой строки. Хотите ли вы иметь доступ ко всем соответствующим символам новой строки? Если это так, то лучше всего захватить все теги содержимого, а затем найти все символы перевода строки, расположенные между ними. Нечто подобное:
<content>.*</content>
НО ЕСТЬ ОДНА ПРОБЛЕМА: регулярные выражения являются жадными, поэтому это регулярное выражение будет сопоставлять первый открывающий тег с последним закрывающим. Вместо этого вы должны подавить регулярное выражение, чтобы оно не было жадным. В таких языках, как python, вы можете сделать это с помощью "?" символ регулярного выражения
Я надеюсь, что с этим вы сможете увидеть некоторые подводные камни и выяснить, как вы хотите действовать. Вероятно, вам лучше использовать библиотеку синтаксического анализа XML, а затем перебирать все теги содержимого.
Я знаю, что, возможно, не буду предлагать лучшее решение, но, по крайней мере, я надеюсь, что вы увидите трудности в этом и почему другие ответы могут быть неправильными...
ОБНОВЛЕНИЕ 1:
Позвольте мне подвести итог немного подробнее и добавить некоторые подробности в мой ответ. Я собираюсь использовать синтаксис регулярных выражений в Python, потому что это то, к чему я больше привык (простите меня заранее... возможно, вам придется экранировать некоторые символы... прокомментируйте мой пост, и я исправлю его):
Чтобы удалить комментарии, используйте это регулярное выражение: обратите внимание на "?" подавляет.*, чтобы сделать его не жадным.
Аналогично, для поиска тегов содержимого используйте: .*?
Кроме того, вы можете попробовать это и получить доступ к каждому символу новой строки с помощью групп объектов соответствия ():
<content>(.*?(\n))+.*?</content>
Я знаю, что мое побег выключен, но это отражает идею. Этот последний пример, вероятно, не сработает, но я думаю, что лучше всего выразить то, что вы хотите. Мое предложение остается: либо возьмите все теги содержимого и сделайте это самостоятельно, либо используйте библиотеку синтаксического анализа.
ОБНОВЛЕНИЕ 2:
Так вот код Python, который должен работать. Я до сих пор не уверен, что вы подразумеваете под "найти" все новые строки. Вы хотите целые строки? Или просто посчитать, сколько новых строк. Чтобы получить реальные строки, попробуйте:
#!/usr/bin/python
import re
def FindContentNewlines(xml_text):
# May want to compile these regexes elsewhere, but I do it here for brevity
comments = re.compile(r"<!--.*?-->", re.DOTALL)
content = re.compile(r"<content>(.*?)</content>", re.DOTALL)
newlines = re.compile(r"^(.*?)$", re.MULTILINE|re.DOTALL)
# strip comments: this actually may not be reliable for "nested comments"
# How does xml handle <!-- <!-- --> -->. I am not sure. But that COULD
# be trouble.
xml_text = re.sub(comments, "", xml_text)
result = []
all_contents = re.findall(content, xml_text)
for c in all_contents:
result.extend(re.findall(newlines, c))
return result
if __name__ == "__main__":
example = """
<!-- This stuff
ought to be omitted
<content>
omitted
</content>
-->
This stuff is good
<content>
<p>
haha!
</p>
</content>
This is not found
"""
print FindContentNewlines(example)
Эта программа печатает результат:
['', '<p>', ' haha!', '</p>', '']
Первая и последняя пустые строки происходят от символов новой строки, непосредственно предшествующих первой <p>
и тот, который идет сразу после </p>
, В целом это (по большей части) делает свое дело. Поэкспериментируйте с этим кодом и уточните его для своих нужд. Распечатайте материал посередине, чтобы вы могли видеть, какие регулярные выражения совпадают и не совпадают.
Надеюсь это поможет:-).
PS - мне не повезло, попробовав свое регулярное выражение из моего первого обновления, чтобы захватить все новые строки... дайте мне знать, если вы это сделаете.