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

Данная статья показывает способ извлечение ссылок из HTML документа с помощью регулярного выражения в среде Java. Например, получить ссылку из текста примерно следующего содержания:

Это текст до ссылки <a href="http://j4web.ru" target="_blank">Это текст самой ссылки</a> Это текст после ссылки

Для этого нам потребуется выполнить два простых действия:

  1. Получить своего род «значение» тега <a> то есть получить полное содержимое тега, заключенное между символами < и >;
  2. Вычленить из полученного на предыдущем шаге текста адрес ссылки.

Регулярное выражение для извлечения HTML ссылок

Регулярное выражение для получения «значения» тега <a>:

(?i)<a([^>]+)>(.+?)</a>
(          # Начало группы 1
  ?i             # Все проверки являются нечувствительными к регистру
)          # Конец группы 1
<a         # Начало ссылки должно быть "<a"
(          # Начало группы 2
  [^>]+          # Все что угодно, кроме ">", как минимум - один символ
)          # Конец группы 2
>          # А потом - символ ">"
(.+?)      # Внутри ссылки может быть все, что угодно
</a>       # В конце - загрывающи тег </a>

Регулярное выражение для извлечения адреса ссылки из текста:

s*(?i)hrefs*=s*("([^"]*")|'[^']*'|([^'">s]+))
s*          # Не может начинаться с пробельного символа
(?i)         # Все проверки нечувствительны к регистру
href         # Далее должно быть ключевое слово "href"
s*=s*      # Слева от знака равенства допускается наличие пробельных симоволов
(            # Начало группы 1
  "([^"]*")          # Строка, азключенная в двойные кавычки - "string"
  |          # Или
  '[^']*'            # Строка, заключенная в одинарные кавычки - 'string'
  |          # Или
  ([^'">]+)          # Не должно быть одинарных и двойных кавычек и символа ">"
)            # Конец группы 1

Извлечение HTML ссылок

Ниже преставлен код простого Java класса, который позволяет получать ссылки из строки, содержащей HTML текст. Напомним, что для получения полного значения тега <a> мы используем первое регулярное выражение, а для получения адреса ссылки — второе.

package ru.j4web.examples.java.regex.htmllinksextractorexample;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class HTMLLinksExtractor {
    
    private static final String TAG_PATTERN = "(?i)<a([^>]+)>(.+?)</a>";
    private static final String LINK_PATTERN
            = "\s*(?i)href\s*=\s*(\"([^"]*\")|'[^']*'|([^'">\s]+))";
    
    private final Pattern tagPattern, linkPattern;
    private Matcher tagMatcher, linkMatcher;
    
    public HTMLLinksExtractor() {
        tagPattern = Pattern.compile(TAG_PATTERN);
        linkPattern = Pattern.compile(LINK_PATTERN);
    }
    
    public List<Link> extractlinks(final String htmlText) {
        
        List<Link> links = new ArrayList<>();
        
        tagMatcher = tagPattern.matcher(htmlText);
        
        while(tagMatcher.find()) {
            
            String aTag = tagMatcher.group(1);
            String linkText = tagMatcher.group(2);
            
            linkMatcher = linkPattern.matcher(aTag);
            
            if(linkMatcher.find()) {
                
                String link = linkMatcher.group(1);
                
                Link linkObject = new Link();
                linkObject.setLink(link);
                linkObject.setLinkText(linkText);
                
                links.add(linkObject);
            }
        }
        
        return links;
    }
    
    public class Link {
        
        String link;
        String linkText;
        
        public Link() {
        }
        
        public Link(final String link, final String linkText) {
            this.link = link;
            this.linkText = linkText;
        }

        public String getLink() {
            return replaceInvalidChars(link);
        }

        public void setLink(String link) {
            this.link = link;
        }

        public String getLinkText() {
            return linkText;
        }

        public void setLinkText(String linkText) {
            this.linkText = linkText;
        }
        
        @Override
        public String toString() {
            return new StringBuilder("[Link : URL = ").append(getLink())
                    .append(", Text = ").append(getLinkText()).append("]")
                    .toString();
        }
        
        private String replaceInvalidChars(String link) {
            link = link.replace("'", "");
            link = link.replace(""", "");
            return link;
        }
    }
}

Тестирование результата

package ru.j4web.examples.java.regex.htmllinksextractorexample;

import java.util.List;
import junit.framework.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class HTMLLinkExtractorTest {
    
    private static HTMLLinksExtractor extractor;
    private static final String LINK = "http://www.j4web.ru";
    
    @BeforeClass
    public static void setUpClass() throws Exception {
        extractor = new HTMLLinksExtractor();
    }
    
    @DataProvider
    public Object[][] linksDataProvider() {
        return new Object[][] {
            new Object[] { "текст до ссылки 1 <a href='" + LINK
                + "'>текст ссылки</a>" },
        new Object[] { "текст до ссылки 2 <a HREF='" + LINK
                + "'>текст ссылки 2</a>" },
        new Object[] { "текст до ссылки 3 <A HREF='" + LINK
                + "'>текст ссылки 3</A> , "
        + "еще немного текста 3 <A HREF='" + LINK
                + "' target='_blank'>еще текст ссылки 3</A>" },
        new Object[] { "текст до ссылки 4 <A HREF='" + LINK
                + "' target='_blank'>текст ссылки 4</A>" },
        new Object[] { "текст до ссылки 5 <A target='_blank' HREF='"
                + LINK + "'>текст ссылки 5</A>" },
        new Object[] { "текст <b>до</b> ссылки <A target='_blank' HREF=""
                + LINK + "">текст ссылки 6</A>" },
        new Object[] { "текст до ссылки 7 <a HREF=" + LINK
                + ">текст ссылки 7</a>" }
        };
    }
    
    @Test(dataProvider="linksDataProvider")
    public void linksExtractorTest(final String htmlText) {
        List<HTMLLinksExtractor.Link> links = extractor.extractlinks(htmlText);
        System.out.println("===================");
        System.out.println("HTML text: " + htmlText);
        System.out.println("Links:");
        for(final HTMLLinksExtractor.Link link: links) {
            System.out.println(" -> " + link.toString());
            Assert.assertEquals(LINK, link.getLink());
        }
    }
}
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running ru.j4web.examples.java.regex.htmllinksextractorexample.HTMLLinkExtractorTest
===================
HTML text: текст до ссылки 1 <a href='http://www.j4web.ru'>текст ссылки</a>
Links:
 -> [Link : URL = http://www.j4web.ru, Text = текст ссылки]
===================
HTML text: текст до ссылки 2 <a HREF='http://www.j4web.ru'>текст ссылки 2</a>
Links:
 -> [Link : URL = http://www.j4web.ru, Text = текст ссылки 2]
===================
HTML text: текст до ссылки 3 <A HREF='http://www.j4web.ru'>текст ссылки 3</A> , еще немного текста 3 <A HREF='http://www.j4web.ru' target='_blank'>еще текст ссылки 3</A>
Links:
 -> [Link : URL = http://www.j4web.ru, Text = текст ссылки 3]
 -> [Link : URL = http://www.j4web.ru, Text = еще текст ссылки 3]
===================
HTML text: текст до ссылки 4 <A HREF='http://www.j4web.ru' target='_blank'>текст ссылки 4</A>
Links:
 -> [Link : URL = http://www.j4web.ru, Text = текст ссылки 4]
===================
HTML text: текст до ссылки 5 <A target='_blank' HREF='http://www.j4web.ru'>текст ссылки 5</A>
Links:
 -> [Link : URL = http://www.j4web.ru, Text = текст ссылки 5]
===================
HTML text: текст <b>до</b> ссылки <A target='_blank' HREF="http://www.j4web.ru">текст ссылки 6</A>
Links:
 -> [Link : URL = http://www.j4web.ru, Text = текст ссылки 6]
===================
HTML text: текст до ссылки 7 <a HREF=http://www.j4web.ru>текст ссылки 7</a>
Links:
 -> [Link : URL = http://www.j4web.ru, Text = текст ссылки 7]
Tests run: 7, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.465 sec

Results :

Tests run: 7, Failures: 0, Errors: 0, Skipped: 0

------------------------------------------------------------------------
BUILD SUCCESS
------------------------------------------------------------------------

Оставить комментарий

Ваш email нигде не будет показанОбязательные для заполнения поля помечены *

*