简体   繁体   English

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

[英]On Which Line Number Was the Regex Match Found?

I would like to search a .java file using Regular Expressions and I wonder if there is a way to detect one what lines in the file the matches are found.我想使用正则表达式搜索.java文件,我想知道是否有一种方法可以检测文件中找到匹配项的行。

For example if I look for the match hello with Java regular expressions, will some method tell me that the matches were found on lines 9, 15, and 30?例如,如果我使用 Java 正则表达式查找匹配hello ,是否有方法告诉我在第 9、15 和 30 行找到匹配项?

Possible... with Regex Trickery! 可能...使用Regex Trickery!

Disclaimer: This is not meant to be a practical solution, but an illustration of a way to use an extension of a terrific regex hack. 免责声明:这并不意味着是一个实际的解决方案,而是说明了使用出色的正则表达式hack扩展的一种方式。 Moreover, it only works on regex engines that allow capture groups to refer to themselves. 而且,它仅在允许捕获组引用自己的正则表达式引擎上起作用。 For instance, you could use it in Notepad++, as it uses the PCRE engine—but not in Java. 例如,您可以在Notepad ++中使用它,因为它使用了PCRE引擎,但在Java中却没有。

Let's say your file is: 假设您的文件是:

some code
more code
hey, hello!
more code

At the bottom of the file, paste :1:2:3:4:5:6:7 , where : is a delimiter not found in the rest of the code, and where the numbers go at least as high as the number of lines. 在文件底部,粘贴:1:2:3:4:5:6:7 ,其中:是在其余代码中找不到的定界符,并且其中的数字至少与的数字一样高。线。

Then, to get the line of the first hello , you can use: 然后,要获得第一个hello ,您可以使用:

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

The line number of the first line containing hello will be captured by Group 2. 组2将捕获包含hello的第一行的行号。

  • In the demo , see Group 2 capture in the right pane. 演示中 ,请参阅右窗格中的第2组捕获。
  • The hack relies on a group referring to itself. 黑客依赖于指称自己的团体。 In the classic @Qtax trick, this is done with (?>\\1?) . 在经典的@Qtax技巧中,这是通过(?>\\1?) For diversity, I used a conditional instead. 为了实现多样性,我改用了有条件的。

Explanation 说明

  • The first part of the regex is a line skipper, which captures an increasing amount of the the line counter at the bottom to Group 1 正则表达式的第一部分是跳线器,它捕获到组1底部越来越多的行计数器
  • The second part of the regex matches hello and captures the line number to Group 2 正则表达式的第二部分匹配hello并捕获到第2组的行号
  • Inside the line skipper, (?:^(?:(?!hello).)*(?:\\r?\\n)) matches a line that doesn't contain hello. 在跳线内部, (?:^(?:(?!hello).)*(?:\\r?\\n))匹配不包含hello的行。
  • Still inside the line skipper, the (?=[^:]+((?(1)\\1):\\d+)) lookahead gets us to the first : with [^:]+ then the outer parentheses in ((?(1)\\1):\\d+)) capture to Group 1... if Group 1 is set (?(1)\\1) then Group 1, then, regardless, a colon and some digits. 仍在跳过框内, (?=[^:]+((?(1)\\1):\\d+))提前将我们带到第一个: [^:]+然后在((?(1)\\1):\\d+))捕获到组1 ...如果设置了组1 (?(1)\\1)然后是组1,则无论冒号和一些数字如何。 This ensures that each time the line skipper matches a line, Group 1 expands to a longer portion of :1:2:3:4:5:6:7 这样可确保每次跳线匹配一条线时,组1都会扩展到:1:2:3:4:5:6:7的较长部分
  • The * mataches the line skipper zero or more times *跳线次数达到零次或多次
  • .*hello matches the line with hello .*hello将行与hello匹配
  • The lookahead (?=[^:]+((?(1)\\1)+:(\\d+))) is identical to the one in the line skipper, except that this time the digits are captured to Group 2: (\\d+) 先行(?=[^:]+((?(1)\\1)+:(\\d+)))是相同的一个在线路船长,不同之处在于此时的数字被捕获到2组: (\\d+)
  • - --

Reference 参考

If you are using a Unix based OS / terminal, you could use sed: 如果您使用的是基于Unix的OS /终端,则可以使用sed:

sed -n '/regex/=' file

(from this StackOverflow response ) (来自此StackOverflow响应

There are no methods in Java that will do it for you. Java中没有任何方法可以帮助您。 You must read the file line-by-line and check for a match on each line. 您必须逐行读取文件,并检查每行是否匹配。 You can keep an index of the lines as you read them and do whatever you want with that index when a match is found. 您可以在阅读时保留行的索引,并在找到匹配项时对索引进行任何操作。

Another solution (workaround) is to:另一种解决方案(解决方法)是:

just append line numbers to the File , line by line, before you process (regex match) it.在处理(正则表达式匹配)之前,只需将 append 行号逐行添加到文件中。

stackoverflow: how to append line numbers to the File stackoverflow:如何将 append 行号添加到文件中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM