Unit-тест написан с использованием библиотеки TestNG 5.10. Как запустить тесты TestNG в Eclipse читайте здесь.
Поиск тега A в HTML-коде с помощью регулярного выражения
Выражение:
(?i)<a([^>]+)>(.+?)</a>
Поиск ссылки в HTML-коде с помощью регулярного выражения
\s*(?i)href\s*=\s*(\"([^"]*\")|'[^']*'|([^'">\s]+));
Комментарии:
( # начало первой группы ?i # без учета регистра ) # конец первой группы <a # начинается с "<a" ( # начало второй группы [^>]+ # один или более любых символов, исключая ">" ) # конец второй группы > # далее следует ">" (.+?) # любое совпадение </a> # оканчивается "</a>
\s* # может начинаться с пробела (?i) # без учета регистра href # слово href \s*=\s* # далее следует символ "=", который может быть окружен любым количеством пробелов (0 или более) ( # начало первой группы "([^"]*") # строка в двойных кавычках - "string" | # или '[^']*' # строка в одинарных кавычках - 'string' | # или ([^'">]+) # не может содержать одинарную кавычку, двойную кавычку и ">" ) # конец первой группы
Пример на Java:
package ru.topcode.skillbase.regexp; import java.util.ArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; public class HTMLLinkExtrator { private Pattern patternTag, patternLink; private Matcher matcherTag, matcherLink; private static final String HTML_A_TAG_PATTERN = "(?i)<a([^>]+)>(.+?)</a>"; private static final String HTML_A_HREF_TAG_PATTERN = "\\s*(?i)href\\s*=\\s*(\"([^\"]*\")|'[^']*'|([^'\">\\s]+))"; public HTMLLinkExtrator() { patternTag = Pattern.compile(HTML_A_TAG_PATTERN); patternLink = Pattern.compile(HTML_A_HREF_TAG_PATTERN); } /** * Поиск ссылок с помощью регулярных выражений * * @param html * html-код * @return Список ссылок и текстов ссылок */ public ArrayList<HtmlLink> grabHTMLLinks(final String html) { ArrayList<HtmlLink> result = new ArrayList<HtmlLink>(); matcherTag = patternTag.matcher(html); while (matcherTag.find()) { String href = matcherTag.group(1); // href String linkText = matcherTag.group(2); // текст ссылки matcherLink = patternLink.matcher(href); while (matcherLink.find()) { String link = matcherLink.group(1); // ссылка result.add(new HtmlLink(link, linkText)); } } return result; } public class HtmlLink { String link; String linkText; public HtmlLink(String link, String linkText) { this.link = link; this.linkText = linkText; } @Override public String toString() { return new StringBuffer("Ссылка : ").append(this.link).append( " Текст ссылки : ").append(this.linkText).toString(); } } }
Unit Test:
package ru.topcode.skillbase.regexp.test; import java.util.ArrayList; import org.testng.Assert; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import ru.topcode.skillbase.regexp.HTMLLinkExtrator; import ru.topcode.skillbase.regexp.HTMLLinkExtrator.HtmlLink; public class HTMLLinkExtratorTest { private HTMLLinkExtrator htmlLinkExtrator; @BeforeClass public void initData() { htmlLinkExtrator = new HTMLLinkExtrator(); } @DataProvider public Object[][] HTMLContentProvider() { return new Object[][] { new Object[] { "abc hahaha <a href='http://www.google.com'>google</a>" }, new Object[] { "abc hahaha <a HREF='http://www.google.com'>google</a>" }, new Object[] { "abc hahaha <A HREF='http://www.google.com'>google</A> , " + "abc hahaha <A HREF='http://www.google.com' target='_blank'>google</A>" }, new Object[] { "abc hahaha <A HREF='http://www.google.com' target='_blank'>google</A>" }, new Object[] { "abc hahaha <A target='_blank' HREF='http://www.google.com'>google</A>" }, new Object[] { "abc hahaha <a HREF=http://www.google.com>google</a>" }, }; } @Test(dataProvider = "HTMLContentProvider") public void ValidHTMLLinkTest(String html) { ArrayList<HtmlLink> links = htmlLinkExtrator.grabHTMLLinks(html); Assert.assertTrue(links.size() != 0); for (int i = 0; i < links.size(); i++) { HtmlLink htmlLinks = links.get(i); System.out.println(htmlLinks); } } }
Результат выполнения теста:
Ссылка : 'http://www.google.com' Текст ссылки : google Ссылка : 'http://www.google.com' Текст ссылки : google Ссылка : 'http://www.google.com' Текст ссылки : google Ссылка : 'http://www.google.com' Текст ссылки : google Ссылка : 'http://www.google.com' Текст ссылки : google Ссылка : 'http://www.google.com' Текст ссылки : google Ссылка : http://www.google.com Текст ссылки : google PASSED: ValidHTMLLinkTest("abc hahaha <a href='http://www.google.com'>google</a>") PASSED: ValidHTMLLinkTest("abc hahaha <a HREF='http://www.google.com'>google</a>") PASSED: ValidHTMLLinkTest("abc hahaha <A HREF='http://www.google.com'>google</A> , abc hahaha <A HREF='http://www.google.com' target='_blank'>google</A>") PASSED: ValidHTMLLinkTest("abc hahaha <A HREF='http://www.google.com' target='_blank'>google</A>") PASSED: ValidHTMLLinkTest("abc hahaha <A target='_blank' HREF='http://www.google.com'>google</A>") PASSED: ValidHTMLLinkTest("abc hahaha <a HREF=http://www.google.com>google</a>") =============================================== ru.topcode.skillbase.regexp.test.HTMLLinkExtratorTest Tests run: 6, Failures: 0, Skips: 0 ===============================================
Для углубленного изучения регулярных выражений в Java рекомендую посетить соответствующий раздел The Java Tutorials и изучить книги из раздела RegExp в библиотеке TopCode.


Pingback: 10 регулярных выражений, которые будут полезны каждому Java-программисту | Java EE Dev
#1 by Oxygen on 26 Август 2010 - 10:23
Quote
Спасибо большое! Не могли бы вы написать регулярное выражение, которое ещё позволяет вынимать пареметры href, id, title из тега?
#2 by Дмитрий Леонтьев on 26 Август 2010 - 12:18
Quote
Исходный текст:
Регулярное выражение: (href)=["']?((?:.(?!["']?\s+(?:\S+)=|[>"']))+.)["']?
Найдет атрибуты href во всех тегах: href=test.html, href=”test.html” и href=’test.html’
#3 by Алекс on 14 Август 2011 - 15:34
Quote
Подскажите какие параметры нужно вбить что бы найти на html странице первую попавшуюся ссылку и какой командой ее можно вставить в место под ссылку в другом скрипте который будет идти сразу после этого скрипта.
#4 by Настя on 4 Декабрь 2011 - 17:05
Quote
А вот я делала почти тоже самое только с php , и вот мне интересно. можно ли сделать парсер на java ?