Python и re.compile возвращают противоречивые результаты

1

Я пытаюсь заменить все экземпляры href="../directory" на href="../directory/index.html".

В Python этот

reg = re.compile(r'<a href="../(.*?)">')
for match in re.findall(reg, input_html):
    output_html = input_html.replace(match, match+'index.html')

выводит следующий результат:

href="../personal-autonomy/index.htmlindex.htmlindex.htmlindex.html"  
href="../paternalism/index.html"  
href="../principle-beneficence/index.htmlindex.htmlindex.html"  
href="../decision-capacity/index.htmlindex.htmlindex.html" 

Любая идея, почему она работает со второй ссылкой, а другие нет?

Соответствующая часть источника:

<p> 

 <a href="../personal-autonomy/">autonomy: personal</a> |
 <a href="../principle-beneficence/">beneficence, principle of</a> |
 <a href="../decision-capacity/">decision-making capacity</a> |
 <a href="../legal-obligation/">legal obligation and authority</a> |
 <a href="../paternalism/">paternalism</a> |
 <a href="../identity-personal/">personal identity</a> |
 <a href="../identity-ethics/">personal identity: and ethics</a> |
 <a href="../respect/">respect</a> |
 <a href="../well-being/">well-being</a> 

</p> 

EDIT: повторяющийся "index.html" на самом деле является результатом нескольких совпадений. (например, href= "../personal-autonomy/index.htmlindex.htmlindex.htmlindex.html", потому что.. /personal -autonomy встречается четыре раза в исходном источнике).

Как общий вопрос с регулярным выражением, как бы вы заменили все экземпляры без добавления дополнительного "index.html" ко всем совпадениям?

  • 1
    Не могли бы вы показать нам, что вклад, а также, пожалуйста?
  • 1
    Почему вы пытаетесь разобрать HTML с регулярным выражением? Существует множество мощных синтаксических анализаторов, которые могут легко извлечь эти операторы, читая DOM. Regex не был разработан для HTML.
Показать ещё 1 комментарий
Теги:

5 ответов

5
Лучший ответ

Не анализировать html с регулярными выражениями:

import re    
from lxml import html

def replace_link(link):
    if re.match(r"\.\./[^/]+/$", link):
        link += "index.html"
    return link

print html.rewrite_links(your_html_text, replace_link)

Выход

<p> 

 <a href="../personal-autonomy/index.html">autonomy: personal</a> |
 <a href="../principle-beneficence/index.html">beneficence, principle of</a> |
 <a href="../decision-capacity/index.html">decision-making capacity</a> |
 <a href="../legal-obligation/index.html">legal obligation and authority</a> |
 <a href="../paternalism/index.html">paternalism</a> |
 <a href="../identity-personal/index.html">personal identity</a> |
 <a href="../identity-ethics/index.html">personal identity: and ethics</a> |
 <a href="../respect/index.html">respect</a> |
 <a href="../well-being/index.html">well-being</a> 

</p>
  • 0
    Спасибо, это работает отлично, за исключением того, что полный вывод заполнен специальными символами (и т. Д.). Есть ли что-то, что мне нужно сделать до или после вызова html.rewrite?
  • 1
    @cyrus: передайте your_html_text как Unicode (используйте .decode() ). Кодируйте возвращаемое значение rewrite_links() используя кодировку, понятную вашей консоли, например, s.encode(sys.stdout.encoding or locale.getpreferredencoding()) .
Показать ещё 3 комментария
1

Думаю, я узнал о проблеме

reg = re.compile(r'<a href="../(.*?)">')

for match in re.findall(reg, input_html):

output_html = input_html.replace(match, match+'index.html')

Здесь 'input_html' изменяется внутри цикла for, а затем снова выполняется поиск 'input_html' для регулярного выражения, которое является ошибкой:)

  • 0
    Иметь другую переменную для сохранения результата
0

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

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

reg = re.compile(r'<a href="(\.\./.*?)">')
0

Увязаете ли вы свои первые два .?

reg = re.compile(r'<a[ ]href="[.][.]/(.*?)">')

Но я бы попытался использовать lxml.

  • 0
    В python вы избегаете метасимвола внутри регулярного выражения с помощью ``
  • 0
    почему это имеет значение в этом случае?
0

В вашем регулярном выражении есть ошибка в том, что .. не соответствует двум точкам. Вместо этого это . metacharacter. Чтобы обозначить точку, вам нужно ее избежать.

Ваше регулярное выражение должно быть: <a href="\.\./(.*?)"

Кроме того, если предположить, что все ваши href имеют форму.. /somedirectory/, вы можете уйти с более простым регулярным выражением:

for match in re.compile(r'<a href="(.*?)"').findall(html):
    html = html.replace(match, match + "index.html")

Здесь регулярное выражение соответствует

<a href="    # start of the taf and attribute
(            # start of a group
 .*          # any character, any number of times
)            # end of group
"            # end of the attribute
  • 0
    Спасибо, Родриг. Это все еще производит тот же результат, как бы то ни было.
  • 0
    Также было бы немного не повезло, если бы теги оказались на одной линии, я думаю
Показать ещё 7 комментариев

Ещё вопросы

Сообщество Overcoder
Наверх
Меню