Мне было интересно, можно ли использовать не жадную стратегию сопоставления для разделенных групп?
Хочу сопоставить что-нибудь между <>. Например:
<a href = "aabbcc"> xxx </a> <a href = "aabbcc"> aabbcc </a>
Я хочу получить последний aabbcc, поэтому написал:
(.*)(>.*)(?<![a-zA-Z])(aabbcc)(?![a-zA-Z])(.*<.*)
Я хочу получить и заменить последний "aabbcc" между <a> и </a> и оставить другие группы без изменений, в этом случае это сработало.
Однако в неправильной ситуации он будет соответствовать aabbcc.
https://regex101.com/r/OeZDu5/1/
Может ли кто-нибудь сказать мне, как использовать нежадную стратегию в этом случае или предоставить мне другие решения?
Почему бы не использовать настоящий HTML-парсер?
Да, используйте для этого анализатор XML. Решение с регулярным выражением будет хрупким и в дальнейшем подвержено ошибкам.
Невозможно воспроизвести: regex101.com/r/RiZ59e/1
Да. Я использую java. Этих тегов нет в html файлах. Они находятся в файле настроек конфигурации, где некоторые строки содержат тег.
Regex101 не имеет тестера регулярных выражений Java. Возможно, есть некоторые тонкие различия между правилами регулярных выражений java и php.
Затем опубликуйте минимальный воспроизводимый пример. Кроме того, что мешает вам запустить некоторые настройки через анализатор HTML, если они содержат код HTML?
Прошу прощения за свою вину. Мельпомена была права. Это сработало на regex101.com/r/RiZ59e/1 Однако у меня в этом случае возникли проблемы regex101.com/r/OeZDu5/1




public static String replace(String s, String target, String newString) {
String regex1 = "(.*)(<.*?>)(.*)";
Pattern pattern = Pattern.compile(regex1);
Matcher matcher1 = pattern.matcher(s);
//System.out.println(s);
if (matcher1.matches()) {
String tmp1 = replace(matcher1.group(1), target, newString);
String tmp2 = replace(matcher1.group(3), target, newString);
return tmp1 + matcher1.group(2) + tmp2;
} else {
String regex2a = "(.*)(?<![a-zA-Z])(";
String regex2b = ")(?![a-zA-Z])(.*)";
String regex2 = regex2a + target + regex2b;
pattern = Pattern.compile(regex2);
Matcher matcher2 = pattern.matcher(s);
if (matcher2.matches()) {
s = replace(matcher2.group(1),target,newString) + newString + replace(matcher2.group(3),target,newString);
}
return s;
}
}
Оставьте group2 в покое, чтобы строки в <> остались нетронутыми.
Попробуйте этот пример:
String input = "<a href=\"aabbcc\"> xxx </a> <a href=\"aabbcc\"> aabbcc </a>\n"
+ "<a href=\"aa\">ppp</a><a href=\"yy\">zz</a>";
System.out.println( "--input--" );
System.out.println( input );
String regexx = "<[^>]+>.*<[^>]+>[ ]*<[^>]+>(.*)<[^>]+>";
Pattern pattern = Pattern.compile( regexx );
Matcher matcher = pattern.matcher( input );
System.out.println( "values:" );
while ( matcher.find() )
{
System.out.println( matcher.group( 1 ) );
}
Надеюсь, что это поможет вам.
А вы пытаетесь сделать это на Java? Не JavaScript? Потому что в JavaScript было бы разумнее просто использовать
.innerHTML. А для Java лучше подойдет парсер HTML.