Regex сопоставить все вхождения, используя обратную ссылку
Я пытаюсь использовать обратную ссылку для сопоставления всех экземпляров импортируемого класса, создаваемого с использованием ripgrep
с --pcre2
опция включена.
Сначала я смотрю, импортируется ли класс, а затем снова обращаюсь к нему, чтобы посмотреть, где он создан.
Первая попытка: соответствует первому появлению
new ExifInterface(str)
Мое регулярное выражение:(import.+(ExifInterface)).+(new\s\2\(.+\))
Вторая попытка: соответствует последнему появлению
new ExifInterface(str)
, Мое регулярное выражение(import.+(ExifInterface)).+(?:.+?(new\s\2\(.+\)))
мой ripgrep
команда rg --pcre2 --multiline-dotall -U "(import.+(ExifInterface)).+(new\s\2\(.+?\))" -r '$3' -o
Вопрос Как я могу сопоставить все вхождения new ExifInterface(str)
Бонусный вопрос: в некоторых случаях я получаю PCRE2: error matching: match limit exceeded
Стдерр из rg
, но не могу понять, почему. Длина документа составляет всего 161 строчку.
Рассмотрим следующую выборку данных:
import android.graphics.Point;
import android.media.ExifInterface;
import android.view.WindowManager;
import java.io.IOException;
public class MediaUtils {
/* renamed from: a */
public static float m13571a(String str) {
if (str == null || str.isEmpty()) {
throw new IllegalArgumentException("getRotationDegreeForImage requires a valid source uri!");
}
try {
int attributeInt = new ExifInterface(str).getAttributeInt("Orientation", 1);
if (attributeInt == 3) {
return 180.0f;
new ExifInterface(str).getAttributeInt("Orientation", 1);
}
if (attributeInt == 6) {
return 90.0f;
}
2 ответа
Строго регулярное выражение PCRE, которое находит последовательные совпадения после начальной
конкретное совпадение это. Он использует \G
конструкция, которая начинает
следующий поиск, где остановилась последняя позиция совпадения.
(?:import.+\bExifInterface\b|(?!^)\G)[\S\s]+?\K\bnew\s+ExifInterface\s*\([\S\s]+?\)
https://regex101.com/r/e6L5rV/1
Не используйте какие-либо флаги, кроме //g
глобальный флаг.
Expanded:
(?:
import .+ \b ExifInterface \b
|
(?! ^ )
\G
)
[\S\s]+?
\K
\b new \s+ ExifInterface \s* \( [\S\s]+? \)
Альтернатива: вы можете получить то, что вы хотите, используя два grep
команды (первая возвращает имена файлов каждого файла, который содержит import.*ExifInterface
, второй находит где экземпляры).
grep -no 'new ExifInterface(' $(grep -lr 'import.*ExifInterface' *)
То же самое можно сделать с помощью ripgrep:
rg -noF 'new ExifInterface(' $(rg -l 'import.*ExifInterface')