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 строчку.

Ссылка на regex101

Рассмотрим следующую выборку данных:

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')
Другие вопросы по тегам