Регулярное выделение тегов HTML

У меня есть этот ввод HTML:

<font size="5"><p>some text</p>
<p> another text</p></font>

Я хотел бы использовать regex для удаления тегов HTML, чтобы выход:

some text
another text

Может ли кто-нибудь предложить, как это сделать с помощью регулярного выражения?

Ответ 1

Вы можете пойти с парсером HTML под парсером Jericho Html.

вы можете скачать его здесь - http://jericho.htmlparser.net/docs/index.html

Иерихон HTML Parser - это Java-библиотека, позволяющая анализировать и обрабатывать части HTML-документа, включая теги на стороне сервера, при одновременном воспроизведении дословно любого непризнанного или недопустимого HTML. Он также обеспечивает высокоуровневые функции обработки формы HTML.

Наличие плохо отформатированного HTML не мешает анализу

Ответ 2

Поскольку вы спросили, вот быстрое и грязное решение:

String stripped = input.replaceAll("<[^>]*>", "");

(демонстрация Ideone.com)

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

  • <tag attribute=">">Hello</tag>
  • <script>if (a < b) alert('Hello>');</script>

и др.

Лучшим подходом было бы использовать, например, Jsoup. Чтобы удалить все теги из строки, вы можете, например, сделать Jsoup.parse(html).text().

Ответ 3

Использовать парсер HTML. Здесь приведен пример Jsoup.

String input = "<font size=\"5\"><p>some text</p>\n<p>another text</p></font>";
String stripped = Jsoup.parse(input).text();
System.out.println(stripped);

Результат:

some text another text

Или, если вы хотите сохранить символы новой строки:

String input = "<font size=\"5\"><p>some text</p>\n<p>another text</p></font>";
for (String line : input.split("\n")) {
    String stripped = Jsoup.parse(line).text();
    System.out.println(stripped);
}

Результат:

some text
another text

Jsoup предлагает больше преимуществ. Вы можете легко извлечь определенные части документа HTML с помощью метода select(), который принимает jQuery-подобные CSS-селектора. Это требует, чтобы документ был семантически хорошо сформирован. Наличие признанного тега <font> с 1998 года уже не очень хорошим показателем, но если вы заранее знаете структуру HTML подробно, это все равно выполнимо.

См. также:

Ответ 4

Начиная с кода aioobe, я попробовал что-то более смелое:

String input = "<font size=\"5\"><p>some text</p>\n<p>another text</p></font>";
String stripped = input.replaceAll("</?(font|p){1}.*?/?>", "");
System.out.println(stripped);

Код для разметки каждого тега HTML будет выглядеть так:

public class HtmlSanitizer {

    private static String pattern;

    private final static String [] tagsTab = {"!doctype","a","abbr","acronym","address","applet","area","article","aside","audio","b","base","basefont","bdi","bdo","bgsound","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dir","div","dl","dt","element","em","embed","fieldset","figcaption","figure","font","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","isindex","kbd","keygen","label","legend","li","link","listing","main","map","mark","marquee","menu","menuitem","meta","meter","nav","nobr","noframes","noscript","object","ol","optgroup","option","output","p","param","plaintext","pre","progress","q","rp","rt","ruby","s","samp","script","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","title","tr","track","tt","u","ul","var","video","wbr","xmp"};

    static {
        StringBuffer tags = new StringBuffer();
        for (int i=0;i<tagsTab.length;i++) {
            tags.append(tagsTab[i].toLowerCase()).append('|').append(tagsTab[i].toUpperCase());
            if (i<tagsTab.length-1) {
                tags.append('|');
            }
        }
        pattern = "</?("+tags.toString()+"){1}.*?/?>";
    }

    public static String sanitize(String input) {
        return input.replaceAll(pattern, "");
    }

    public final static void main(String[] args) {
        System.out.println(HtmlSanitizer.pattern);

        System.out.println(HtmlSanitizer.sanitize("<font size=\"5\"><p>some text</p><br/> <p>another text</p></font>"));
    }

}

Я написал это для того, чтобы быть совместимым с Java 1.4, по некоторым грустным причинам, поэтому не стесняйтесь использовать для каждого и StringBuilder...

Преимущества:

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

Недостатки:

  • Вам нужно перечислить все теги HTML, которые вы хотите удалить из своей строки. Что может быть много, например, если вы хотите все разбить.

Если у вас появятся другие недостатки, я действительно буду рад их узнать.

Ответ 5

Если вы используете Jericho, вам просто нужно использовать что-то вроде этого:

public String extractAllText(String htmlText){
    Source source = new Source(htmlText);
    return source.getTextExtractor().toString();
}

Конечно, вы можете сделать то же самое даже с Element:

for (Element link : links) {
  System.out.println(link.getTextExtractor().toString());
}