Java не жадное регулярное выражение с разделенными группами

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

Хочу сопоставить что-нибудь между <>. Например:

<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/

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

А вы пытаетесь сделать это на Java? Не JavaScript? Потому что в JavaScript было бы разумнее просто использовать .innerHTML. А для Java лучше подойдет парсер HTML.

Obsidian Age 29.05.2018 06:09

Почему бы не использовать настоящий HTML-парсер?

melpomene 29.05.2018 06:10

Да, используйте для этого анализатор XML. Решение с регулярным выражением будет хрупким и в дальнейшем подвержено ошибкам.

Tim Biegeleisen 29.05.2018 06:12

Невозможно воспроизвести: regex101.com/r/RiZ59e/1

melpomene 29.05.2018 06:12

Да. Я использую java. Этих тегов нет в html файлах. Они находятся в файле настроек конфигурации, где некоторые строки содержат тег.

Myquist 29.05.2018 06:56

Regex101 не имеет тестера регулярных выражений Java. Возможно, есть некоторые тонкие различия между правилами регулярных выражений java и php.

Myquist 29.05.2018 07:11

Затем опубликуйте минимальный воспроизводимый пример. Кроме того, что мешает вам запустить некоторые настройки через анализатор HTML, если они содержат код HTML?

melpomene 29.05.2018 07:17

Прошу прощения за свою вину. Мельпомена была права. Это сработало на regex101.com/r/RiZ59e/1 Однако у меня в этом случае возникли проблемы regex101.com/r/OeZDu5/1

Myquist 29.05.2018 07:25
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
8
75
2

Ответы 2

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 ) );
    }

Надеюсь, что это поможет вам.

Другие вопросы по теме

Как извлечь повторяющуюся часть строки?
Замените первый пробел между двумя цифрами косой чертой
Регулярное выражение PCRE для удаления пробела перед точкой и добавления одной после нее, но не влияет на многоточие
Дублируйте строку внутри файла и перезапишите другую с помощью sed
Регулярное выражение, чтобы найти большой кусок текста между разделителями
Необязательно сопоставление символа с использованием утверждения просмотра назад
Как использовать regExp, чтобы найти значение в ячейке и поместить в следующую строку в электронной таблице?
Webpack - как использовать загрузчик для файла, заканчивающегося заданной строкой?
Регулярное выражение: как создать шаблон для соответствия хотя бы одному символу нижнего регистра, символу верхнего регистра, цифре и хотя бы одному символу между [$ @ # &!]
НЕКОТОРЫЕ символы табуляции не совпадают в сценариях оболочки, но совпадают в командной строке