Сопоставление окружающего текста вокруг группового совпадения

Вот пример:

<li><a href="link" target="_parent">1. Tips and tricks</a></li>

регулярное выражение:

/tips(?![^<]*>)/ig

Соответствует слову Советы.

Что я хочу сделать, так это иметь возможность сопоставлять окружающий текст, возможно, в другой группе?

Таким образом, совпадение может быть e.g. ["1. Tips and tricks", "Tips"].

Вы можете протестировать его здесь


person viperfx    schedule 09.07.2014    source источник
comment
Почему бы вам не использовать парсер HTML вместо регулярных выражений?   -  person jonrsharpe    schedule 09.07.2014
comment
Что именно вы ищете? Весь текст между тегами <a>?   -  person Jerry    schedule 09.07.2014
comment
Я пытаюсь найти только текстовые узлы, и я обнаружил, что использование регулярных выражений намного проще, чем обход DOM. Причина в том, что я перевожу язык текста, поэтому мне нужна только текстовая информация.   -  person viperfx    schedule 09.07.2014


Ответы (3)


Я думаю, вы пытаетесь получить это,

>>> import re
>>> str = '<li><a href="link" target="_parent">1. Tips and tricks</a></li>'
>>> m = re.findall(r'((?<=>)\d+\.\s*(Tips)[^<]*)', str)
>>> m
[('1. Tips and tricks', 'Tips')]

ИЛИ

>>> str = """
... <li>
... <a href="link" target="_parent">
... 1. Tips and tricks
... </a>
... </li>"""
>>> m = re.findall(r'\s*<a[^>]*>\n(\s*\S*\s*(\S*)[^\n]*)', str)
>>> m
[('1. Tips and tricks', 'Tips')]
person Avinash Raj    schedule 09.07.2014
comment
Я использую re.finditer, и, похоже, он не возвращает никаких результатов для первого решения. - person viperfx; 09.07.2014
comment
Второе решение не работает, потому что некоторые html-теги все еще оставлены. - person viperfx; 09.07.2014
comment
не могли бы вы опубликовать фактический ввод в pastebin? - person Avinash Raj; 09.07.2014
comment
Это был просто пример. Он должен соответствовать любому символу между › и ‹. - person viperfx; 09.07.2014

Следуя вашему комментарию, я думаю, что гораздо проще использовать BeautifulSoup, а затем использовать re.split для очистки немного вверх:

from bs4 import BeautifulSoup
import re

html = """<li class="selected ">
<a href="http://localhost:8888/translate_url" target="_parent">
          Learn the Basics: get iniciared
        </a>
<ul class="subtopics">
<li>
<a href="http://localhost:8888/translate_url" target="_parent">
                Tips and tricks
                </a>
</li>
<li>
<a href="http://localhost:8888/translate_url" target="_parent">
                Use bookmarks
                </a>
</li>"""

soup = BeautifulSoup(html)
text = re.split(r'\s{2,}', soup.get_text().strip())

Выход:

['Learn the Basics: get iniciared', 'Tips and tricks', 'Use bookmarks']

soup.get_text() получает весь текст на странице. Затем используйте strip() для удаления начальных и конечных пробелов, чтобы в списке текста не было пустых строк.

person Jerry    schedule 09.07.2014

В документации Python для модуля re указано, что:

Подгруппы нумеруются слева направо, от 1 вверх. Группы могут быть вложенными; чтобы определить число, просто посчитайте символы открывающей скобки, идущие слева направо.

Так, например, следующий (некрасивый) шаблон будет соответствовать окружающему тексту в одной группе и целевому слову из ссылки в вашем примере:

/[^\n\s](.*basics(?![^<]*>).*)\n/ig

Вы можете уточнить это для вашего случая!

Изменить: Использование регулярных выражений для анализа HTML по-прежнему является довольно плохой идеей, что-то вроде beautifulsoup было бы более надежным.

person Brett Lempereur    schedule 09.07.2014
comment
Я пытаюсь найти только текстовые узлы, и я обнаружил, что использование регулярных выражений намного проще, чем обход DOM. Причина в том, что я перевожу язык текста, поэтому мне нужна только текстовая информация. Я использовал BeautifulSoup, но я обнаружил, что это больше работы по сравнению с тем, что легко делает регулярное выражение. - person viperfx; 09.07.2014