在Java中使用正则表达式的g标志

10
在Java模式中使用正则表达式全局g标志是否可能?我尝试使用final Pattern pattern = Pattern.compile(regex,Pattern.DOTALL);,但它的行为不像全局标志。在Java中是否有任何解决方法?我的正则表达式是:
private final String regex ="(public|private|protected|static|final|abstract|synchronized|volatile)\\s*([\\w<>\\[\\]]+)\\s*(\\w+)\\s*\\(([\\w\\s\\w,<>\\[\\]]*)?\\)\\s*(\\bthrows\\b)?[\\s\\w\\s,\\w]*\\{[\\n\\t]*(.+)[\\n\\t]*((return|throw){1}\\s*)(\\w*)\\s*;\\s*[\\}]";输入是文件内容,类似于下面链接中提到的正则表达式:https://regex101.com/r/u7vanR/3。我希望Java模式能够找到两个出现,但使用Java正则表达式标志时,它只找到第一个而不是两个。

1
看起来该页面上的正则表达式默认将 .* 视为懒惰模式。在Java中,您需要显式地使用 .*? 来匹配最小量的文本。此外,您不需要用 [...] 包围转义的 \\}(它已经被 \\ 转义了)。 - Pshemo
我不确定 {1} 的目的是什么。如果没有指定量词,那么默认情况下正则表达式会搜索单个匹配项,因此通常我们不需要编写 {1}。如果正则表达式具有其他量词,如 {2} {3},则可能会有用,以显示哪些部分应该存在一次、两次、三次等等。 - Pshemo
1
我不会说这与特定的正则表达式无关,因为Java默认设置了全局标志(而且你甚至不能关闭它)。但是如果您无法正确匹配某些内容,则问题很可能在于模式。在您的情况下,可能的原因是.*,默认情况下它是贪婪的,因此它尝试尽可能匹配更多文本,根据您链接中的数据,它看起来像是将所有方法作为一个匹配项进行匹配(例如第一个方法的开头{ .*最后一个方法的结尾})。解决方法可能是使用.*?使.*变得勉强。 - Pshemo
如果您仍然遇到问题,为了提供适当的帮助,我们需要查看[mcve]和您实际想要实现的描述。 - Pshemo
@Pshemo 谢谢,我也会尝试。我之前没有用过 .*,而是用的 .+,所以我需要将它改为 .+?另外,你正确指出了 {1} 和 \} 与 [...] 不是必需的。但是上面的正则表达式与链接中提到的相同(不带 Java 语法),并且正确匹配两个部分,但在 Java 中使用时,行为不同。 - Sandeep Chauhan
显示剩余2条评论
2个回答

15

Java没有全局标志。您可以通过findgroup获取所有匹配项。

Pattern pattern = Pattern.compile("1");
Matcher matcher = pattern.matcher("111");
while (matcher.find()) {
    System.out.println(matcher.group());
}

输出结果为

1
1
1

2
这个正则表达式匹配时不会像使用"g"标志那样找到两个匹配项: https://regex101.com/r/u7vanR/3 - Sandeep Chauhan
1
请编辑您的问题,包括正则表达式模式以及实际结果和期望结果。 - zhh
1
我在问题中添加了我的实际正则表达式,输入是文件内容,就像我在上面给出的链接中提到的那样。 - Sandeep Chauhan

-1
你在Java中不需要使用"g"标志。有一些具有相同效果的方法,例如:
``` replaceAll(regex, replacement) ```

1
这并没有回答楼主的问题。 - Ed Graham

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