用正则表达式\ w \ w *拆分字符串? \ w +?

问题描述 投票:4回答:3

我正在学习regexp,并认为我开始抓紧了。但是之后...

我试图拆分一个字符串,我需要帮助来理解这样一个简单的事情:

String input = "abcde";
System.out.println("[a-z] " + Arrays.toString(input.split("[a-z]")));
System.out.println("\\w " + Arrays.toString(input.split("\\w")));
System.out.println("\\w*? " + Arrays.toString(input.split("\\w*?")));
System.out.println("\\w+? " + Arrays.toString(input.split("\\w+?")));

The output is
[a-z] - []
\w    - []
\w*?  - [, a, b, c, d, e]
\w+?  - []

为什么两个第一行中的任何一行都没有在任何字符上拆分字符串?第三个表达式\ w *?,(问号防止贪婪)按照我的预期工作,在每个字符上分割字符串。星号,零个或多个匹配项返回一个空数组。

我在NotePad ++和程序中尝试了表达式,它显示了5个匹配项,如:

Scanner ls = new Scanner(input);
while(ls.hasNext())
    System.out.format("%s ", ls.findInLine("\\w");

Output is: a b c d e

这真让我困惑

java regex
3个回答
10
投票

如果使用正则表达式拆分字符串,则基本上可以告诉应该剪切字符串的位置。这必然会削减你与正则表达式相匹配的东西。这意味着如果你在\w分割,那么每个字符都是一个分裂点,它们之间的子串(全部为空)都会被返回。 Java会自动删除尾随的空字符串,如the documentation中所述。

这也解释了为什么懒惰匹配\w*?会给你每个角色,因为它将匹配任何角色(零宽度)之间(和之前和之后)的每个位置。剩下的是字符串本身的字符。

让我们分解一下:

  1. [a-z]\w\w+? 你的字符串是 abcde 比赛如下: a b c d e └─┘└─┘└─┘└─┘└─┘ 这将留下匹配之间的子串,所有这些都是空的。 上述三个正则表达式在这方面表现相同,因为它们只匹配单个字符。 \w+?会这样做,因为它没有任何其他限制可能使+?尝试匹配不仅仅是最低限度(毕竟它是懒惰的)。
  2. \w*? a b c d e └┘ └┘ └┘ └┘ └┘ └┘ 在这种情况下,匹配位于字符之间,使您具有以下子字符串: "", "a", "b", "c", "d", "e", "" 不过,Java会抛弃尾随的空尾。

3
投票

让我们打破每次对String#split(String)的调用。从Java文档中注意到“方法的工作原理就好像通过使用给定的表达式调用the two-argument split method并且限制参数为零。因此,尾随的空字符串不包含在结果数组中。”

"abcde".split("[a-z]"); // => []

这个匹配每个字符(a,b,c,d,e)并且只产生它们之间的空字符串,这些字符串被省略。

"abcde".split("\\w")); // => []

同样,字符串中的每个字符都是一个单词字符(\w),因此结果是空字符串,省略。

"abcde".split("\\w*?")); // => ["", "a", "b", "c", "d", "e"]

在这种情况下,*表示“前面项目中的零个或多个”(\w),它与空表达式匹配七次(一次在字符串的开头,然后在每个字符之间一次)。所以我们得到第一个空字符串然后每个字符。

"abcde".split("\\w+?")); // => []

这里+表示“前面的一个或多个项目”(\w),它匹配整个输入字符串,只产生空字符串,省略。

使用input.split(regex, -1)再次尝试这些示例,您应该看到所有空字符串。


1
投票

String.split在模式的每个匹配中剪切字符串:

此方法返回的数组包含此字符串的每个子字符串,该子字符串由与给定表达式匹配的另一个子字符串终止,或者由字符串的结尾终止。

因此,只要匹配[a-z]这样的模式,就会在该匹配时剪切字符串。由于字符串中的每个字符都与模式匹配,因此结果数组为空(删除尾随空字符串)。

这同样适用于\w\w+?(一个或多个\w,但尽可能少重复)。那个\w*?导致你预期的东西是由于*?量词,因为如果可能的话,它将匹配零重复,所以一个空字符串。并且在给定字符串中的每个位置都找到一个空字符串。

© www.soinside.com 2019 - 2024. All rights reserved.