【问题标题】:On Which Line Number Was the Regex Match Found?在哪个行号上找到了正则表达式匹配?
【发布时间】:2014-07-14 04:02:11
【问题描述】:

我想使用正则表达式搜索.java 文件,我想知道是否有一种方法可以检测文件中找到匹配项的行。

例如,如果我使用 Java 正则表达式查找匹配 hello,是否有方法告诉我在第 9、15 和 30 行找到匹配?

【问题讨论】:

  • 除了将相关行添加到列表之外?
  • 你有没有尝试过?
  • 不止于此。这已经足够了......我尝试使用索引计数器和扫描仪逐行读取整个文件,但这似乎没有必要,我无法通过正则表达式找到方法。
  • “我想知道是否有任何方法可以检测到我的匹配项在代码中的哪一行”。当然,逐行阅读并尝试匹配,如果匹配则打印行号。简单!
  • 好吧,我猜我现在有什么计数器是最好的方法?

标签: java regex


【解决方案1】:

可能...使用正则表达式技巧!

免责声明:这并不是一个实用的解决方案,而是说明如何使用一个了不起的 regex hack 扩展的方法。此外,它仅适用于允许捕获组引用自己的正则表达式引擎。例如,您可以在 Notepad++ 中使用它,因为它使用 PCRE 引擎,但不能在 Java 中使用。

假设您的文件是:

some code
more code
hey, hello!
more code

在文件底部粘贴:1:2:3:4:5:6:7,其中: 是其余代码中没有的分隔符,其中数字至少与行数一样高。

然后,要获取第一个hello 的行,可以使用:

(?m)(?:(?:^(?:(?!hello).)*(?:\r?\n))(?=[^:]+((?(1)\1):\d+)))*.*hello(?=[^:]+((?(1)\1)+:(\d+)))

包含hello的第一行的行号将被Group 2捕获。

  • the demo 中,请参阅右侧窗格中的第 2 组捕获。
  • hack 依赖于引用自身的组。在经典的@Qtax 技巧中,这是通过(?>\1?) 完成的。为了多样性,我改用了条件句。

说明

  • 正则表达式的第一部分是一个换行符,它捕捉到第 1 组底部越来越多的行计数器
  • 正则表达式的第二部分匹配 hello 并将行号捕获到第 2 组
  • 在换行符内,(?:^(?:(?!hello).)*(?:\r?\n)) 匹配不包含 hello 的行。
  • 仍在换行符内,(?=[^:]+((?(1)\1):\d+)) 前瞻将我们带到第一个:[^:]+ 然后((?(1)\1):\d+)) 中的外括号捕获到第1 组...如果第1 组设置为(?(1)\1) 然后第 1 组,然后,无论如何,一个冒号和一些数字。这确保了每次换行符匹配一行时,第 1 组扩展为 :1:2:3:4:5:6:7 的较长部分
  • * 匹配换行符零次或多次
  • .*hellohello 匹配
  • 前瞻(?=[^:]+((?(1)\1)+:(\d+))) 与换行符中的前行相同,只是这次将数字捕获到第 2 组:(\d+)
  • -

参考

【讨论】:

    【解决方案2】:

    如果您使用的是基于 Unix 的操作系统/终端,则可以使用 sed:

    sed -n '/regex/=' file
    

    (来自StackOverflow response

    【讨论】:

    • 这并没有真正尝试回答这个问题。 OP 声明在 Java 中使用正则表达式。
    • 他想在 java 文件中查找行号。使用 sed,他可以使用类似:sed -n '/hello/=' foo.java
    • 虽然这是一个解决方案,但 OP 声明“如果我使用 Java 正则表达式查找匹配 hello,是否会有一些方法...” ,这意味着使用 Java、基于 Unix 的操作系统和终端将是不同的依赖关系。
    • 问题只是关于使用正则表达式和确定行号。使用 java 正则表达式的示例并没有说明使用 java 解决问题的要求。 Renlo给出的解决方案简单易行。只需将“regex”替换为您的正则表达式即可。
    【解决方案3】:

    Java 中没有任何方法可以为您做到这一点。您必须逐行阅读文件并检查每一行是否匹配。您可以在阅读时保留行的索引,并在找到匹配项时对该索引执行任何操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-16
      • 1970-01-01
      • 1970-01-01
      • 2013-06-19
      • 2021-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多