在哪个行号找到正则表达式匹配?
我想使用正则表达式搜索.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中没有可以为您完成的方法。 您必须逐行读取文件并检查每行的匹配项。 您可以在读取行时保留行的索引,并在找到匹配项时对该索引执行任何操作。