Стоит задача поиска всех не повторяющихся тегов без атрибутов (например, head
, body
) в HTML файле с помощью регулярных выражений.
public static void main(String[] args) throws FileNotFoundException {
String tmp = fileReader(fileName); //метод читает весь файл и возвращает строку, в которой мы ищем наши теги
Pattern p = Pattern.compile("<[^> ]+>");
Matcher m = p.matcher(tmp);
while (m.find()) {
System.out.println(m.group());
}
}
Данный код выводит все теги без атрибутов, а мне нужны только те, которые не повторяются.
Я пробовал так: ("<[^> ]+>")?
. ?
означает, что оно будет искать совпадения, которые повторяются 0 или 1 раз. Не работает.
Как это можно сделать?
Вы не сможете решить эту задачу чистыми регулярками в Java - в движке регулярок этого языка отсутствуют обратные позиционные проверки непостоянной длины, то бишь:
(?<![a-z].*)
Вы можете посмотреть как примерно могло бы выглядеть такое регулярное выражение:
https://regex101.com/r/iH6gR5/1
<(\w+)>(?=.*?(<\/\1>))(?!.*<\1)
Его проблема в том, что оно совпадает с последним DIV, так как справа от него нет другого DIV.
У меня нет .NET для тестирования регулярки (в нем есть ?<!.*
), но рабочий вариант должен выглядеть примерно так:
<(\w+)>(?<!<\1>.*<\1>)(?=.*?(<\/\1>))(?!.*<\1)
P.S. Регулярное выражение не учитывает комментарии, блоки CDATA и прочие прелести синтаксиса HTML, если добавить поддержку этого, то регулярка будет настолько сложной, что не принесет образовательного эффекта.
Не люблю так решать, когда ответ - смесь кода и регулярных выражений, поэтому сначала написал, что задача не решаема при помощи регулярных выражений.
String tmp = "<html><head></head><body><div></div><DIV><pre></pre></div></body></html>";
Pattern p = Pattern.compile( "<([^> ]+)>(?=(?:.*<(\\1)>)?)", Pattern.DOTALL|Pattern.CASE_INSENSITIVE );
Matcher m = p.matcher(tmp);
List<String> exclude = new ArrayList<String>();
while ( m.find() ) {
if ( m.group(2) != null ) {
exclude.add( m.group(2).toLowerCase() );
}
if ( exclude.indexOf( m.group(1).toLowerCase() ) == -1 ) {
System.out.println( m.group() );
}
}
Результат:
<html>
<head>
</head>
<body>
<pre>
</pre>
</body>
</html>
Были исключены div
, так как они повторяются.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Доброго времени сутокЯ столкнулся с такой проблемой: не могу растянуть видео на всю ширину страницы в Adobe Muse
Есть горизонтальный список, состоящий из картинок и заголовков под нимиХочу сделать, чтобы заголовок зависел от ширины картинки
Вот смотрите, http://jsfiddlenet/mgpv8qvt/1/ почему подчеркивание идет над строкой а не под?