Java 正则表达式:如何匹配一个或多个空格字符

8

如何在Java正则表达式中匹配多个空格字符?

我正在尝试匹配一个正则表达式,但当有两个或更多空格字符时,它会失败。

public static void main(String[] args) { 
    String pattern = "\\b(fruit)\\s+([^a]+\\w+)\\b"; //Match 'fruit' not followed by a word that begins with 'a'
    String str = "fruit apple"; //One space character will not be matched
    String str_fail = "fruit  apple"; //Two space characters will be matched
    System.out.println(preg_match(pattern,str)); //False (Thats what I want)
    System.out.println(preg_match(pattern,str_fail)); //True (Regex fail)
}

public static boolean preg_match(String pattern,String subject) {
    Pattern regex = Pattern.compile(pattern);
    Matcher regexMatcher = regex.matcher(subject);
    return regexMatcher.find();
}

1
在Java标准编码规范中,将String $pattern翻译为String pattern - assylias
2
那是...Java代码里的PHP语法吗? - ean5533
3
可能是第二个空格被 [^a] 匹配了(一个空格不是 'a')。 - erikxiv
我的问题是关于正则表达式\s+,它为什么不起作用。PHP 代码看起来是这样的,因为我正在将一个 PHP 应用程序移植到 Java。所有代码(上面的代码)在 Java 中都可以编译。 - MontrealDevOne
1
不要将 PHP 应用程序移植到 Java,这是行不通的。移植功能,但要拥抱 Java。 - Sean Patrick Floyd
1个回答

12
这个问题实际上是由回溯引起的。你的正则表达式:
 "\\b(fruit)\\s+([^a]+\\w+)\\b"

说的是“水果,后跟一个或多个空格,后跟一个或多个非'a'字符,后跟一个或多个'单词'字符”。这个失败的原因是有两个空格,因为\s+匹配第一个空格,但然后放回第二个,然后满足了[^a]+(有第二个空格)和\s+部分(有第一个空格)。
我认为你可以通过简单地使用占有量词来修复它,即\s++。这告诉\s不要放回第二个空格字符。您可以在此处找到有关Java量词符的文档here
作为举例说明,在Rubular上有两个例子:
  1. \s上使用所有格量词(从您的描述中得到预期结果)
  2. 使用[^a\]+\w+周围的单独分组的当前正则表达式。请注意,第二个匹配组(代表[^a]+)正在捕获第二个空格字符。

正确的分析和有效的解决方案。第二个可能的解决方案是将[^a]更改为[^a\s] - ean5533

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