Как использовать регулярные выражения для разбора HTML в Java? - PullRequest
14 голосов
/ 24 марта 2009

Может кто-нибудь сказать мне простой способ найти теги href и src в html-файле, используя регулярные выражения в Java?
А затем, как я могу получить URL-адрес, связанный с тегом?

Спасибо за любые предложения.

Ответы [ 7 ]

53 голосов
/ 24 марта 2009

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

Используйте взамен HTML Parser . См. Также Каковы плюсы и минусы ведущих HTML-парсеров Java?

21 голосов
/ 24 марта 2009

Остальные ответы верны. Java Regex API не является подходящим инструментом для достижения вашей цели. Используйте эффективные, безопасные и хорошо протестированные инструменты высокого уровня, упомянутые в других ответах.

Если ваш вопрос касается скорее Regex API, чем реальной проблемы (например, в целях обучения), вы можете сделать это с помощью следующего кода:

String html = "foo <a href='link1'>bar</a> baz <a href='link2'>qux</a> foo";
Pattern p = Pattern.compile("<a href='(.*?)'>");
Matcher m = p.matcher(html);
while(m.find()) {
   System.out.println(m.group(0));
   System.out.println(m.group(1));
}

И вывод:

<a href='link1'>
link1
<a href='link2'>
link2

Обратите внимание, что ленивый / неохотный квалификатор *? должен использоваться для того, чтобы свести группировку к одному тегу. Группа 0 - это полное совпадение, группа 1 - следующее совпадение группы (следующая пара скобок).

7 голосов
/ 24 марта 2009

Не используйте регулярные выражения, используйте NekoHTML или TagSoup, которые являются мостом, предоставляющим SAX или DOM, как в XML-подходе к посещению документа HTML.

5 голосов
/ 24 марта 2009

Если вы хотите пойти по пути разбора html, который Дэйв и я рекомендую вам, вот код для анализа String Data для тегов привязки и печати их href.

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

File parserLibraryFile = new File("lib/MozillaHtmlParser/native/bin/MozillaParser" + EnviromentController.getSharedLibraryExtension());
                String parserLibrary = parserLibraryFile.getAbsolutePath();
                //  mozilla.dist.bin directory :
                final File mozillaDistBinDirectory = new File("lib/MozillaHtmlParser/mozilla.dist.bin."+ EnviromentController.getOperatingSystemName());

        MozillaParser.init(parserLibrary,mozillaDistBinDirectory.getAbsolutePath());
MozillaParser parser = new MozillaParser();
Document domDocument = parser.parse(data);
NodeList list = domDocument.getElementsByTagName("a");

for (int i = 0; i < list.getLength(); i++) {
    Node n = list.item(i);
    NamedNodeMap m = n.getAttributes();
    if (m != null) {
        Node attrNode = m.getNamedItem("href");
        if (attrNode != null)
           System.out.println(attrNode.getNodeValue());
3 голосов
/ 24 марта 2009

Я искал в библиотеке регулярных выражений (http://regexlib.com/Search.aspx?k=href и http://regexlib.com/Search.aspx?k=src)

Лучшее, что я нашел, было

((?<html>(href|src)\s*=\s*")|(?<css>url\())(?<url>.*?)(?(html)"|\))

Проверьте эти ссылки для дополнительных выражений:

http://regexlib.com/REDetails.aspx?regexp_id=2261

http://regexlib.com/REDetails.aspx?regexp_id=758

http://regexlib.com/REDetails.aspx?regexp_id=774

http://regexlib.com/REDetails.aspx?regexp_id=1437

1 голос
/ 25 марта 2009

Вопреки распространенному мнению, регулярные выражения являются полезными инструментами для извлечения данных из неструктурированного текста (что такое HTML).

Если вы выполняете сложное извлечение данных HTML (скажем, находите все абзацы на странице), то, вероятно, вам стоит разобрать HTML. Но если вам просто нужно получить некоторые URL-адреса от HREF, то регулярное выражение будет работать нормально, и его будет очень сложно взломать.

Попробуйте что-то вроде этого:

/<a[^>]+href=["']?([^'"> ]+)["']?[^>]*>/i
0 голосов
/ 25 марта 2009

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

HTML-парсеры, с другой стороны, может анализировать HTML, поэтому они называются HTML-парсерами.

Вместо этого вы должны использовать свой любимый HTML-парсер.

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