import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Example {
public static void main(String[] args) {
final String regex = "(?(DEFINE) #Это блок с объявлением функций\n\n"
+ " #Этот блок - единственное место, где нужно подставлять значения\n"
+ " (?<tagName>ul) #Имя тега\n"
+ " (?<attrName>class) #Атрибут тега\n"
+ " (?<attrValue>ul) #Значение тега\n\n"
+ " (?<anyAttrName>[^\\s\\>\\=]*+) #Любое название атрибута\n"
+ " (?<anyAttrValue>\\\"[^\\\"]*+\\\"|\\'[^\\']*+\\'|\\`[^\\']*+\\`|[^\\s\\>]*+) #Любое значение атрибута\n"
+ " (?<anyAttr>(?&anyAttrName)\\s*+(?:\\=\\s*+(?&anyAttrValue)\\s*+)?+) #Любой атрибут\n\n"
+ " #Если нужно найти точное вхождение значения атрибута\n"
+ " (?<attr>\n"
+ " (?&attrName)\\b\\s*+\\=\\s*+ #Нужное нам название атрибута\n"
+ " (?: #Поиск точного вхождения\n"
+ " \\\"(?&attrValue)\\\"|\n"
+ " \\'(?&attrValue)\\'|\n"
+ " \\`(?&attrValue)\\`|\n"
+ " (?&attrValue)(?=[\\s\\>])\n"
+ " )\n"
+ " )\n\n"
+ " #Если нужно искать в атрибуте значение как в классах\n"
+ " (?<attrClass>\n"
+ " (?&attrName)\\b\\s*+\\=\\s*+ #Нужное нам название атрибута\n"
+ " (?: #Поиск значения как в классах\n"
+ " \\\"[^\\\"]*?\\b(?&attrValue)\\b[^\\\"]*+\\\"|\n"
+ " \\'[^\\']*?\\b(?&attrValue)\\b[^\\']*+\\'|\n"
+ " \\`[^\\`]*?\\b(?&attrValue)\\b[^\\`]*+\\`|\n"
+ " (?&attrValue)(?=[\\s\\>])\n"
+ " )\n"
+ " )\n\n"
+ " #В зависимости от того, какую из 2 функций выше мы хотим использовать для проверки атрибута\n"
+ " #Строгое сравнение значения\n"
+ " (?<tag>\\<(?&tagName)\\b\\s*+(?&anyAttr)*?(?&attr)(?&anyAttr)*?\\>) #Использовать так: (?&tag)\n"
+ " #Поиск значения как в классах\n"
+ " (?<tagClass>\\<(?&tagName)\\b\\s*+(?&anyAttr)*?(?&attrClass)(?&anyAttr)*?\\>) #Использовать так: (?&tagClass)\n\n"
+ ") #Этот огровный блок с функциями закончился\n\n"
+ "(?:[^\\<]++(*SKIP)|\\G|\\C*?(?<parentTag>(?&tagClass)))[^\\<]*+\\K #После того, как нашли тег сбросили состояние нулевой группы\n"
+ "(?<openTag>\\<li\\b\\s*+(?&anyAttr)*+\\>) #У тега могут быть атрибуты\n"
+ "(?<innerHTML>\\C*?) #Внутреннее содержимое тега\n"
+ "(?<closeTag>\n"
+ " \\<\\/li\\b\\s*+(?&anyAttr)*+>| #В HTML у закрывающих тегов нет атрибутов, но HTML от этого не ломается\n"
+ " (?=(?&openTag))| #Теги элементов списка необязательно закрывать согласно документации\n"
+ " (?=(?<closeParentTag>\\<\\/ul\\b\\s*+(?&anyAttr)*+\\>)) #Закрытие списка закрывает последний элемент\n"
+ ")";
final String string = "<ul>\n"
+ " <li class=\"li anyClass\">aaa</li>\n"
+ " <li>bbb\n"
+ " <li>ccc\n"
+ "</ul>\n"
+ "<p>какой-то текст</p>\n"
+ "<ul data-class=\"ul anyClass\" class=\"ul anyClass\" data-id=`ul` id='ul' data-data=ul data-empty>\n"
+ " <li class=\"li anyClass\">aaa</li>\n"
+ " <li >aaa</li>\n"
+ " <li>bbb\n"
+ " <li>ccc\n"
+ "</ul>\n"
+ "<p>какой-то текст</p>\n"
+ "<ul>\n"
+ " <li class=\"li anyClass\">aaa</li>\n"
+ " <li>bbb\n"
+ " <li>ccc\n"
+ "</ul>\n"
+ "<p>какой-то текст</p>\n"
+ "<ul data-class=\"ul anyClass\" class=\"ul anyClass\" data-id=`ul` id='ul' data-data=ul data-empty>\n"
+ " <li class=\"li anyClass\">aaa</li>\n"
+ " <li>bbb\n"
+ " <li>ccc\n"
+ "</ul>\n"
+ "<p>какой-то текст</p>\n"
+ "<ul>\n"
+ " <li class=\"li anyClass\">aaa</li>\n"
+ " <li>bbb\n"
+ " <li>ccc\n"
+ "</ul>";
final Pattern pattern = Pattern.compile(regex, Pattern.COMMENTS | Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
}
}
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for Java, please visit: https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html