Как использовать регулярные выражения для синтаксического анализа HTML в Java?

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

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

Ответы

Ответ 1

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

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

Ответ 2

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

Если ваш вопрос касается скорее 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 - следующее групповое совпадение (следующая пара скобок).

Ответ 3

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

Ответ 4

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

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

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());

Ответ 5

Я обыскал библиотеку регулярных выражений (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

Ответ 6

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

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

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

Ответ 7

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

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

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

/<a[^>]+href=["']?([^'"> ]+)["']?[^>]*>/i