Получить тэги html с их содержимым (RegExp, java)

Рейтинг: 1Ответов: 1Опубликовано: 10.04.2015

Нужно вывести все тэги с их содержимым на экран.

Вот задание:

Вывести на консоль все теги, которые соответствуют заданному тегу Каждый тег на новой строке, порядок должен соответствовать порядку следования в файле Количество пробелов, \n, \r не влияют на результат Файл не содержит тег CDATA, для всех открывающих тегов имеется отдельный закрывающий тег, одиночных тегов нету Тег может содержать вложенные теги

Вот шаблоны тэгов из задания:

<tag>text1</tag>
<tag text2>text1</tag>
<tag
text2>text1</tag>

text1, text2 могут быть пустыми

Ввод такой:

<span>string1 <span>string2</span> string11</span>

Вывод должен быть таким:

<span>string1 <span>string2</span> string11</span>
<span>string2</span>

Какой регэксп для этого нужен? Вот мой тестировочный код:

public class Solution {

    public static void main(String[] args) {

        String testStr = "<span>string1 <span>string2</span> string11</span>";

        Pattern p = Pattern.compile("(\\<(/?[^\\>]+)\\>)");
        Matcher m = p.matcher(testStr);

        while(m.find()) {
            System.out.println(testStr.substring(m.start(), m.end()));
        }

    }
}

Ответы

▲ 2Принят

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

(?=(<span>(?:(?1)|<(?!\/span>)|[^<]*+)*+<\/span>))

Более общее выражение, но еще менее производительное:

(?=(<(span)>(?:(?1)|<(?!\/\2>)|[^<]*+)*+<\/\2>))

Текст:

<span>string1 <span>string2</span><span> string3 <span>string4</span> <span>string5</span> </span> string11</span>

Результат:

<span>string1 <span>string2</span><span> string3 <span>string4</span> <span>string5</span> </span> string11</span>
<span>string2</span>
<span> string3 <span>string4</span> <span>string5</span> </span>
<span>string4</span>
<span>string5</span>

https://regex101.com/r/dG0vP9/2