string.split("\\ S")如何工作

Fra*_*nan 13 java regex ocpjp

我在Ganesh和Sharma的书中提出了一个问题:oracle_certified_professional_java_se_7_programmer_exams_1z0-804_and_1z0-805.

一个问题是:

  1. 考虑以下程序并预测输出:

      class Test {
    
        public static void main(String args[]) {
          String test = "I am preparing for OCPJP";
          String[] tokens = test.split("\\S");
          System.out.println(tokens.length);
        }
      }
    
    Run Code Online (Sandbox Code Playgroud)

    a)0

    b)5

    c)12

    d)16

现在我明白\ S是正则表达式意味着将非空格字符视为分隔符.但我很困惑的是正则表达式如何进行匹配以及split产生的实际标记是什么.

我添加了代码来打印令牌,如下所示

for (String str: tokens){
  System.out.println("<" + str + ">");
}
Run Code Online (Sandbox Code Playgroud)

我得到了以下输出

16

<>

< >

<>

< >

<>

<>

<>

<>

<>

<>

<>

<>

< >

<>

<>

< >
Run Code Online (Sandbox Code Playgroud)

所以很多空字符串令牌.我只是不明白这一点.

我会想到,如果分隔符是非空格字符,那么在上面的文本中,所有字母字符都可以作为分隔符,所以如果我们匹配导致空字符串的标记,也许应该有21个标记.我只是不明白Java的正则表达式引擎如何解决这个问题.是否有任何正则表达的大师可以为我阐明这些代码?

Pab*_*ano 12

从API 文档复制:(粗体是我的)

public String[] split(String regex)
Run Code Online (Sandbox Code Playgroud)

将此字符串拆分为给定正则表达式的匹配项.此方法的工作方式就像调用带有给定表达式和limit参数为零的双参数split方法一样.因此,结尾的空字符串不包含在结果数组中.

例如,字符串"boo:and:foo"会使用以下表达式产生以下结果:

 Regex  Result
   :    { "boo", "and", "foo" }
   o    { "b", "", ":and:f" }
Run Code Online (Sandbox Code Playgroud)

检查第二个示例,其中最后2个"o"被删除:您的问题的答案是"OCPJP"子字符串被视为分隔符的集合,非空字符串不遵循,因此该部分被修剪.


ajb*_*ajb 6

结果是16而不是21的原因是,来自javadocSplit:

因此,结尾的空字符串不包含在结果数组中.

这意味着,例如,如果你说

"/abc//def/ghi///".split("/")
Run Code Online (Sandbox Code Playgroud)

结果将有五个要素.第一个是"",因为它不是一个尾随的空字符串; 别人会"abc","","def",和"ghi".但是剩下的空字符串将从数组中删除.

在发布的案例中:

"I am preparing for OCPJP".split("\\S")
Run Code Online (Sandbox Code Playgroud)

这是同一件事.由于非空格字符是分隔符,因此每个字母都是分隔符, OCPJP字母本质上不计数,因为这些分隔符会导致尾随空字符串,然后将其丢弃.因此,由于有15个字母"I am preparing for",它们被视为划分16个子串(第一个是""最后一个" ").


Pet*_*erK 5

首先要做的是\s(小写),这是白色空间的正则表达式字符类,即空格''tabs'\ t',新行字符'\n'和'\ r',垂直制表符'\''和一堆其他人物.

\S (大写)与此相反,因此这意味着任何非空白字符.

因此,当您I am preparing for OCPJP使用此分割此字符串时,您将\S在每个字母处有效地分割字符串.令牌数组长度为16的原因.

至于为什么这些都是空的.

考虑以下字符串:Hello,World,如果我们要使用它来拆分,,我们最终会得到一个长度为2的String数组,其中包含以下内容:HelloWorld.请注意,,它不在任何一个字符串中,它已被删除.

I am preparing for OCPJP字符串也发生了同样的事情,它已被拆分,正则表达式匹配的点不在任何返回值中.并且因为该String中的大多数字母后跟另一个字母,所以最终会加载长度为零的字符串,只保留空白字符.

  • 问题的关键是:为什么16而不是21?为什么"OCPJP"不被视为一堆分隔符?共有21个字母,但最后一个字母被忽略了...... (5认同)