Сопоставление регулярных выражений между двумя строками?

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

>>> import re
>>> string = '''
... <!-- one 
... -->
... <!-- two -- -- -->
... <!-- three -->
... '''
>>> m = re.findall ( '<!--([^\(-->)]+)-->', string, re.MULTILINE)
>>> m
[' one \n', ' three ']

блок с two -- -- не соответствует, скорее всего, из-за неправильного регулярного выражения. Может кто-нибудь указать мне правильное направление, как извлечь совпадения между двумя строками.


Привет, я проверил то, что вы, ребята, предложили в комментариях... вот рабочее решение с небольшим обновлением.

>>> m = re.findall ( '<!--(.*?)-->', string, re.MULTILINE)
>>> m
[' two -- -- ', ' three ']
>>> m = re.findall ( '<!--(.*\n?)-->', string, re.MULTILINE)
>>> m
[' one \n', ' two -- -- ', ' three ']

Благодарность!


person Hrvoje Špoljar    schedule 04.10.2012    source источник
comment
что-либо между [] является одним символом, поэтому (--›) не будет искать эту группировку, это часть проблемы...   -  person Joran Beasley    schedule 05.10.2012
comment
re.findall('<!--(.*?)-->', string, re.DOTALL) должен делать. Вам не нужно ^\(-->) здесь, потому что вопросительный знак делает его нежадным.   -  person BrtH    schedule 05.10.2012
comment
Ты выглядишь так, будто ищешь только слова? Если да, то что не так с m = re.findall('[\w]+', string, re.MULTILINE)? Кроме того, строка — очень плохое имя для, гм, строки.   -  person Ben    schedule 05.10.2012


Ответы (2)


это должно помочь

 m = re.findall ( '<!--(.*?)-->', string, re.DOTALL)
person iruvar    schedule 04.10.2012
comment
Вам не нужен флаг MULTILINE. - person Alan Moore; 05.10.2012
comment
Если кому-то интересно, флаг re.DOTALL делает точку (.) соответствующей любому символу, включая новую строку. (.*?) фиксирует текст внутри круглых скобок, а .*? означает, что не жадная версия .* (т.е. захват кратчайших возможных совпадений). - person np8; 11.11.2016
comment
Если <!-- и --> должны быть частью результирующих элементов списка, скобки захвата должны быть удалены - re.findall ( '<!--.*?-->', string, re.DOTALL) - person Wiktor Stribiżew; 12.04.2018

В общем случае невозможно выполнить произвольное сопоставление двух разделителей с помощью обычной грамматики.

В частности, если вы разрешаете вложение,

<!-- how do you deal <!-- with nested --> comments? -->

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

Чтобы анализировать произвольные комментарии, вам нужно перейти к методу анализа контекстно-свободных грамматик. Простой способ сделать это — использовать автомат pushdown.

person Wilduck    schedule 04.10.2012
comment
Я не думаю, что вложенные комментарии так уж распространены. Своего рода побеждает смысл комментирования, если что-то внутри него обрабатывается? - person Anuj Gupta; 05.10.2012
comment
И похоже, что они невозможны в HTML. stackoverflow.com/questions/442786/ I Я собираюсь оставить это здесь, потому что я думаю, что это важно признать, но я не ожидаю каких-либо голосов. - person Wilduck; 05.10.2012
comment
Конечные автоматы не могут анализировать контекстно-свободные грамматики - вы можете использовать автоматы Pushdown. - person James Thiele; 05.10.2012
comment
@JamesThiele Аааа, конечно. Я отредактировал ответ, чтобы отразить это - person Wilduck; 05.10.2012