在哪个行号找到正则表达式匹配?

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

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

可能……与Regex Trickery一起!

免责声明:这并不是一个实用的解决方案,而是一个使用极好的正则表达式黑客扩展的方法的说明。 此外,它仅适用于允许捕获组引用自身的正则表达式引擎。 例如,您可以在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捕获。

  • 在演示中 ,请参阅右窗格中的第2组捕获。
  • 黑客依赖于一个自称的群体。 在经典的@Qtax技巧中,这是用(?>\1?) 。 对于多样性,我使用了条件。

说明

  • 正则表达式的第一部分是一个行队长,它捕获了底部的行计数器越来越多的第1组
  • 正则表达式的第二部分匹配hello并将行号捕获到Group 2
  • 在队长里面, (?:^(?:(?!hello).)*(?:\r?\n))匹配一个不包含hello的行。
  • 仍在队长中, (?=[^:]+((?(1)\1):\d+))向前看到我们到第一个:[^:]+然后是外围括号((?(1)\1):\d+))捕获到组1 …如果组1被设置(?(1)\1)然后组1,那么,无论如何,冒号和一些数字。 这确保了每次线条船长与线条匹配时,组1会扩展到更长的部分:1:2:3:4:5:6:7
  • *将线路队长放置零次或多次
  • .*hello将该行与hello匹配
  • 前瞻(?=[^:]+((?(1)\1)+:(\d+)))与行跳船中的前瞻相同,不同之处在于此时数字被捕获到第2组:( (\d+)

参考

  • Qtax技巧 (最近获得了@AmalMurali的额外奖励)
  • 将单词替换为找到它的行号

如果您使用的是基于Unix的OS /终端,则可以使用sed:

 sed -n '/regex/=' file 

(来自此StackOverflow响应 )

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