Regex сопоставить все вхождения, используя обратную ссылку - PullRequest
0 голосов
/ 09 июля 2019

Я пытаюсь использовать обратную ссылку для сопоставления всех экземпляров импортируемого класса, для которого создается экземпляр 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 stderr от rg, но не могу понять, почему. Длина документа составляет всего 161 строку.

Ссылка на регулярное выражение101

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

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 ]

1 голос
/ 09 июля 2019

Строго регулярное выражение PCRE, которое находит последовательные совпадения после начального
конкретное совпадение это. Он использует конструкцию \G, которая запускает
следующий поиск, где остановилась последняя позиция совпадения.

(?:import.+\bExifInterface\b|(?!^)\G)[\S\s]+?\K\bnew\s+ExifInterface\s*\([\S\s]+?\)

https://regex101.com/r/e6L5rV/1

Не используйте никакие флаги, кроме //g глобального флага.

Расширен:

 (?:
      import .+ \b ExifInterface \b 
   |  
      (?! ^ )
      \G 
 )
 [\S\s]+? 
 \K 
 \b new \s+ ExifInterface \s* \( [\S\s]+? \)
0 голосов
/ 09 июля 2019

Альтернатива: вы можете получить то, что хотите, используя две команды grep (первая возвращает имена файлов каждого файла, который содержит import.*ExifInterface, вторая находит, где находятся экземпляры).

grep -no 'new ExifInterface(' $(grep -lr 'import.*ExifInterface' *) 

То же самое можно сделать с помощью ripgrep:

rg -noF 'new ExifInterface(' $(rg -l 'import.*ExifInterface')
...