正则表达式匹配在哪一行找到了?

3
我想使用正则表达式搜索一个 .java 文件,不知道是否有一种方法能够检测文件中哪些行包含匹配的内容。
例如,如果我使用Java正则表达式查找匹配项hello,是否有一种方法可以告诉我匹配项出现在第9行、第15行和第30行?

除了将相关行添加到列表中,还有其他方法吗? - AntonH
我想知道是否有办法检测出代码中匹配的行。当然可以逐行读取并尝试匹配,如果匹配成功则打印该行号。很简单! - Nir Alfasi
好的,我猜现在用计数器的方式是最好的方法了? - goaman
我正在Mac上的Eclipse中运行这个。 - goaman
@goaman 请发布您当前Java实现的相关部分。这将提高未来访问者的整体问题质量。 - Austin Mullins
显示剩余3条评论
4个回答

6

用正则表达式技巧实现可能性!

声明:这并不是一个实际的解决方案,而是演示使用绝妙的正则表达式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”的行的行号将被捕获到第二组中。
  • 演示中,请查看右窗格中的第2组捕获。
  • 该技巧依赖于引用自身的组。在经典的@Qtax技巧中,使用(?>\1?)来实现。为了多样性,我使用了条件语句。

解释

  • 正则表达式的第一部分是“line skipper”,它将底部的行计数器的逐渐增加的部分捕获到第1组中。
  • 正则表达式的第二部分匹配hello并将行号捕获到第2组中。
  • 在“line skipper”内部,(?:^(?:(?!hello).)*(?:\r?\n))匹配不包含hello的行。
  • 仍在“line skipper”内部,前瞻符(?=[^:]+((?(1)\1):\d+))可以带我们到第一个冒号 :,然后外面的括号((?(1)\1):\d+))会将第1组捕获到其中...如果设置了第1组(?(1)\1),则为第1组,否则为冒号和一些数字。这可以确保每次“line skipper”匹配行时,第1组扩展为:1:2:3:4:5:6:7的更长部分。
  • *匹配“line skipper”零次或多次
  • .*hello匹配包含hello的行
  • 前瞻符(?=[^:]+((?(1)\1)+:(\d+)))与“line skipper”中的相同,只是这次将数字捕获到第2组:(\d+)

参考资料


2
如果您正在使用基于Unix的操作系统/终端,您可以使用sed命令:
sed -n '/regex/=' file

这是一个从StackOverflow回复中的段落。

这并没有真正尝试回答问题。OP在Java中提到了正则表达式的使用。 - Unihedron
他想在Java文件中找到行号。使用sed,他可以使用类似以下的命令:sed -n '/hello/=' foo.java - renlo
虽然这是一个解决方案,但 OP 表示“如果我使用 Java 正则表达式查找匹配项 __hello__,是否会有一些方法......”,这意味着使用 Java、基于 Unix 的操作系统和终端将会有不同的依赖关系。 - Unihedron
这个问题只涉及到使用正则表达式和确定行号。使用Java正则表达式的示例并没有说明必须使用Java来解决问题。Renlo提供的解决方案简单易行,只需将“regex”替换为您的正则表达式即可。 - Erin Heyming

0

解决方案(变通方法)M1

只需在处理(正则表达式匹配)文件之前,逐行向文件追加行号

stackoverflow: 如何向文件追加行号

解决方案(变通方法)M2

计算匹配组之前出现的所有换行符

long count_NewLines = Pattern.compile("\\R")
                             .matcher(content.substring(0, matcher.start()))
                             .results()
                             .count() + 1;

0

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



网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接