【问题标题】:Regex match all occurrences using back reference正则表达式使用反向引用匹配所有出现
【发布时间】:2019-07-08 21:13:46
【问题描述】:

我正在尝试使用反向引用来匹配所有使用 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)的所有出现次数

额外问题:在某些情况下,我从rg 得到了一个PCRE2: error matching: match limit exceeded stderr,但不知道为什么。文档长度只有 161 行。

Link to 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;
            }

【问题讨论】:

  • 您使用什么语言?您使用的是 grep 之类的实用程序吗?
  • OP 在第一段中特别提到了ripgrep
  • 哦,我以为他在使用一种语言。本来打算告诉你如何使用 \G 构造来做到这一点,但现在猜不到。
  • 如果 PCRE 支持,那么这里也适用。
  • 支持,但用法是重复匹配,不是grep。 Grep 每次都重新开始。

标签: regex pcre ripgrep


【解决方案1】:

严格的 PCRE 正则表达式,在初始值之后查找连续匹配
具体搭配是这样的。它使用启动
\G构造 next 搜索上次匹配位置停止的位置。

(?: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]+? \)

【讨论】:

  • 这是一个漂亮的正则表达式。但这个小问题是当使用ripgrep 时,它只会显示第一个匹配项。
  • 嗯,我就是这么想的。但是,也许文档可以选择进行 global 匹配,这正是您所需要的。它是 PCRE,是功能齐全的正则表达式。祝你好运!
【解决方案2】:

另一种选择:您可以使用两个grep 命令获得所需的内容(第一个返回包含import.*ExifInterface 的每个文件的文件名,第二个查找实例化的位置)。

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

也可以用 ripgrep 做同样的事情:

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

【讨论】:

  • 我最初的想法是使用 grep,但是当遍历 100+ 个文件时,ripgrep 性能是无与伦比的
  • @securisec:对于 100 多个文件,您不必担心性能问题。另外,不要对基准测试太天真。
  • 你是对的,但是我利用这一点的代码已经围绕 ripgrep 完成了,并且真的不可行切换到使用 grep 而不是 ripgrep。您的回答将对下一个正在寻找此类解决方案的人非常有帮助,但就我而言,我有点坚持自己的要求。
  • 这对于 ripgrep 的工作方式完全相同。只需将grep 替换为rg,并在第二次调用中删除r 标志。
  • @BurntSushi5:确实,左括号也必须转义。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-03
  • 1970-01-01
  • 1970-01-01
  • 2020-07-02
  • 1970-01-01
  • 2010-09-09
相关资源
最近更新 更多