Подтвердить что ты не робот

Регулярное выражение для соответствия каждому новому символу строки (\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>
4b9b3361

Ответ 1

На самом деле... вы не можете использовать простое регулярное выражение здесь, по крайней мере, не одно. Вероятно, вам нужно беспокоиться о комментариях! Кто-то может написать:

<!-- <content> blah </content> -->

Здесь вы можете использовать два подхода:

  • Сначала запишите все комментарии. Затем используйте подход с регулярным выражением.
  • Не используйте регулярные выражения и используйте контекстно-зависимый подход синтаксического анализа, который может отслеживать, вложен ли вы в комментарий.

Будьте осторожны.

Я также не уверен, что вы можете сразу сопоставить все новые строки. @Quartz предложил следующее:

<content>([^\n]*\n+)+</content>

Это будет соответствовать любым тегам контента, у которых есть символ новой строки. ПРАВО ПРЕЖДЕ ЧЕМ закрывающий тег... но я не уверен, что вы подразумеваете, сопоставляя все новые строки. Вы хотите иметь доступ ко всем совпадающим символам новой строки? Если это так, лучше всего захватить все теги контента, а затем искать все символы новой строки, которые вложены между ними. Что-то еще подобное:

<content>.*</content>

НО ЕСТЬ ОДИН ПЕЧАТ: регулярные выражения жадные, поэтому это регулярное выражение будет соответствовать первому открывающему тегу до последнего закрытия. Вместо этого вам нужно подавить регулярное выражение, чтобы оно не было жадным. В таких языках, как python, вы можете сделать это с помощью?? regex.

Я надеюсь, что с этим вы сможете увидеть некоторые подводные камни и выяснить, как вы хотите продолжить. Вероятно, вам лучше использовать библиотеку синтаксического анализа XML, а затем повторить все теги контента.

Я знаю, что я, возможно, не предлагаю лучшего решения, но, по крайней мере, надеюсь, что вы увидите трудности в этом и почему другие ответы могут быть неправильными...

ОБНОВЛЕНИЕ 1:

Позвольте мне подытожить немного больше и добавить некоторые подробности в мой ответ. Я буду использовать синтаксис regex 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 - Мне не очень удавалось проверять мое регулярное выражение из моего первого обновления, чтобы захватить все новые строки... дайте мне знать, если вы это сделаете.

Ответ 2

<content>(?:[^\n]*(\n+))+</content>