Парсинг HTML с помощью регулярных выражений - плохая идея, но она подходит для этой ситуации.
Описание: Учитывая файл .html, я должен проанализировать внутренние ссылки, извлечь уровень отступа, текст ссылки и номер страницы, на которой она находится, во внешний файл .txt, который затем передается кому-то еще.
Итак, учитывая этот пример HTML:
<TR valign="bottom">
<TD valign="top"><DIV style="margin-left:0px; text-indent:-0px"><A href="#101"><FONT style="font-variant:small-caps;">The “Offering“</FONT>
</A></DIV></TD>
<TD> </TD>
<TD nowrap align="right" valign="top"> </TD>
<TD align="right" valign="top">1</TD>
<TD nowrap valign="top"> </TD>
</TR>
<TR valign="bottom">
<TD valign="top"><DIV style="margin-left:15px; text-indent:-0px"><A href="#102">Sales & Property
</A></DIV></TD>
<TD> </TD>
<TD nowrap align="right" valign="top"> </TD>
<TD align="right" valign="top">2</TD>
<TD nowrap valign="top"> </TD>
</TR>
Внешний файл выдаст:
0|The "Offering"|4
15|Sales & Property|5
(номера страниц различаются, потому что это фактический номер страницы, а не ссылка на фолио).
У меня это в основном разобрано, за исключением 1 части, когда текст ссылки содержит дополнительные коды HTML, такие как тег <Font>
в первой ссылке.
Вот мое регулярное выражение для извлечения ссылок (примечание $ string содержит HTML выше):
while ($string =~ m/<DIV style="margin-left:([0-9]+)px; text-indent:[-0-9]+px"><A href="#([0-9]+)">([a-zA-Z0-9\.,:;&#\s]+)<\/A>/gi) {
push(@indents,$1);
push(@linkIDs,$2);
push(@names,escapeHTML($3));
};
Это правильно извлечет второй, но не первый, из-за> <и других символов в коде HTML. </p>
Если я изменю эту последнюю группу захвата на .+
или .*
, я получу весь файл HTML (ну, между первым <Div><A>
и последним </A>
. Кажется, что шаблон начинается с начало, но совпадает с концом файла назад.
Вот ссылка на онлайн-конструктор регулярных выражений: http://regexr.com? 2s0po
Он правильно находит то, что мне нужно, но в Perl я не получаю те же результаты (только весь упомянутый файл).
Кажется, я не могу написать что-нибудь, что будет правильно захватывать каждую группу - вы могли бы подумать, что «курсор» переместится вперед и остановится на первой </A>
, которую он увидел с начала файла.
Любая помощь или мнения или рекомендации будут с благодарностью. -Спасибо.