Я пытаюсь заменить все экземпляры 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" ко всем совпадениям?
Не анализировать 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>
your_html_text
как Unicode (используйте .decode()
). Кодируйте возвращаемое значение rewrite_links()
используя кодировку, понятную вашей консоли, например, s.encode(sys.stdout.encoding or locale.getpreferredencoding())
.
Думаю, я узнал о проблеме
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' для регулярного выражения, которое является ошибкой:)
Проблема заключается в том, что содержимое а-тега также соответствует тому, что вы пытаетесь заменить.
Это никоим образом не идеальный способ сделать это, но я думаю, вы найдете, что он работает правильно, если вы замените регулярное выражение:
reg = re.compile(r'<a href="(\.\./.*?)">')
Увязаете ли вы свои первые два .
?
reg = re.compile(r'<a[ ]href="[.][.]/(.*?)">')
Но я бы попытался использовать lxml.
В вашем регулярном выражении есть ошибка в том, что ..
не соответствует двум точкам. Вместо этого это .
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