Как использовать регулярные выражения для синтаксического анализа 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