Java получить группу с Regex Matcher - PullRequest
1 голос
/ 25 февраля 2020

Я хочу заменить replaceEntry (@length) на newEntry, но есть некоторые replaceEntrys с дополнительным содержимым, которые я не хочу заменять (например, @ length.article). Если я просто ищу шаблон, не группируя его, он заменяет replaceEntry и следующий символ, но я просто хочу заменить запись. Неправильно ли Regex или что-то еще?

private String replace(String code){
String code = "@length Lorem ipsum dolor sit amet, consetetur sadipscing elitr, @length.article sed diam 
               nonumy eirmod tempor invidunt ut labore et dolore magna @length.media aliquyam erat, sed 
               diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd 
               gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem @length_name 
               ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt 
               ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et 
               justo duo dolores et @length ea rebum. Stet clita kasd gubergren, no sea takimata sanctus 
               est Lorem ipsum dolor sit amet. @length";

String replaceEntry = "@length";
String newEntry = "@column";

Pattern pattern = Pattern.compile("(" + replaceEntry + ")([^\\w-\\.])");
        Matcher matcher = pattern.matcher(code);

        String newCode = code.replaceAll(matcher.group(1), newEntry);

        return newCode;
}

Ответы [ 2 ]

0 голосов
/ 25 февраля 2020

Вы можете исправить свой шаблон, заменив группу захвата ([^\\w-\\.]) на шаблон "(?![\\w.-])" с отрицательным прогнозом , не потребляющий шаблон, который читает , проверяет строку, но не добавляет соответствующую подстроку к значению совпадения.

Вы можете использовать

Pattern.compile(replaceEntry + "(?![\\w.-])")

См. демонстрационную версию regex .

Или, если список replaceEntry может содержать элемент с специальными метасимволами регулярных выражений , используйте Pattern.quote(), чтобы экранировать их и рассматривать как буквенные символы:

Pattern.compile(Pattern.quote(replaceEntry) + "(?![\\w.-])")

Если replaceEntry всегда заканчивается пробелом или концом строки, вы можете просто положиться на границу пробела:

Pattern.compile(Pattern.quote(replaceEntry) + "(?!\\S)")

См. regex demo .

(?!\S) Отрицательный взгляд требует пробела или конца строки непосредственно справа от текущего местоположения.

При замене не забудьте использовать группу 0, все совпадение:

String newCode = code.replaceAll(matcher.group(), newEntry);
                                              ^^

Если нет дополнительных строк кода, вы можете уменьшить три строки

Pattern pattern = Pattern.compile("(" + replaceEntry + ")([^\\w-\\.])");
Matcher matcher = pattern.matcher(code);
String newCode = code.replaceAll(matcher.group(1), newEntry);

до

String newCode = code.replaceAll(Pattern.quote(replaceEntry) + "(?![\\w.-])", newEntry);
0 голосов
/ 25 февраля 2020

Вы должны использовать предвидение, чтобы захватить группу без следующих символов , но все еще сможет прочитать их. Пример

@length(?!\.)

Это соответствует @ length , затем убедитесь, что точка не может быть прочитана после (но не читает точку)

@length and @length are @length.details соответствует: по индексу 0 [@length], по индексу 12 [@length]

...