\s 无法匹配所有的空白字符。

6
在我的Java 8应用程序中,我正在扫描传入的文本中的空格。但是我的正则表达式中的\s不能捕获所有的空格。在我的测试中,我发现它无法捕获其中的一个空格,即不间断空格(Unicode 00A0)。这是我的正则表达式,遇到了这个问题:
Pattern p = Pattern.compile("\\s");

为解决这个问题,我在我的正则表达式中添加了\h
Pattern p = Pattern.compile("[\\s\\h]");

现在,我还需要注意哪些不会被\s\h捕获的其他空格?


3
"\v" 是其中之一。 - Andy Turner
匹配所有空格字符的最简单方法是 "\\p{Z}"Z 是 Unicode 通用类别;请参阅 http://unicode.org/reports/tr44/#General_Category_Values。 - VGR
1
@VGR \\p{Z} 不匹配 \t\n - Holger
@Holger Huh,你说得对。我以为它们已经包含在内了。\r\u000b也没有被包括在内。它们都被归类为控制字符。所以,我想我会使用"[\\s\\p{Z}]"。我认为这覆盖了所有情况... - VGR
3
@VGR或\p{IsWhiteSpace}(?U)\s,因为\u000b\r\n\t属于“控制”类别,但具有二进制属性“空格”。 - Holger
@Holger 非常有用的信息。我之前认为 White_Space 二进制属性与 Z 类别本质上是相同的。 - VGR
3个回答

10

默认情况下,\s 只匹配 ASCII 空白字符 ([ \t\n\x0B\f\r])。有两种方法可以克服这个限制:

  1. 使用 Unicode 字符属性:Pattern.compile("\\p{IsWhiteSpace}")

  2. 使预定义字符类使用 Unicode 属性:
    Pattern.compile("\\s", Pattern.UNICODE_CHARACTER_CLASS)
    这也可以通过嵌入标志 (?U) 启用。

Pattern[] pattern = {
    Pattern.compile("\\s"),
    Pattern.compile("\\s", Pattern.UNICODE_CHARACTER_CLASS),
    Pattern.compile("((?U)\\s)"),
    Pattern.compile("\\p{IsWhiteSpace}")
};
String s = " \t\n\u00A0\u2002\u2003\u2006\u202F";
for(Pattern p: pattern) {
    int count = 0;
    for(Matcher m = p.matcher(s); m.find(); ) count++;
    System.out.printf("%-19s: %d matches%n",
      p.pattern()+((p.flags()&Pattern.UNICODE_CHARACTER_CLASS)!=0? " [(?U) via flags]": ""),
      count);
}

\s                 : 3 matches
\s [(?U) via flags]: 8 matches
((?U)\s)           : 8 matches
\p{IsWhiteSpace}   : 8 matches

4
根据 Pattern 类文档,与 \s 匹配的字符是 \t\n\x0B\f\r
然而,Unicode 确实支持更多的 空格字符。例如:
  • \u2002:En 空格
  • \u2003:Em 空格
  • \u2003:细空格
  • \u202F:窄不间断空格

从阅读 Pattern 文档并测试这些空格字符来看,似乎 /v 将是我需要添加到正则表达式中的唯一额外空格匹配器。谢谢。 - Jack Cole
1
好的,所以我将页面上所有空白(没有标记)的Unicode字符复制到一个字符串中,并使用以下正则表达式成功解析它们:Pattern.compile("(?:[\\s\\h\\v\\u2009\\u200B]|\\uDB40\\uDC20)*") - Jack Cole

2
我们在这方面使用guava...最初的回答。
String s = " \t\n\u00A0\u2002\u2003\u2006\u202F";
int b = CharMatcher.whitespace().countIn(s);
System.out.println(b); // 8

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