我正在学习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
这真让我困惑
答案 0 :(得分:10)
如果使用正则表达式拆分字符串,则基本上可以告诉应该剪切字符串的位置。这必然会削减你与正则表达式相匹配的东西。这意味着如果您在\w
处拆分,则每个字符都是一个拆分点,并返回它们之间的子串(全部为空)。 Java会自动删除尾随的空字符串,如the documentation。
这也解释了为什么延迟匹配\w*?
将为您提供每个字符,因为它将匹配任何字符(零宽度)之间(和之前和之后)的每个位置。剩下的就是字符串本身的字符。
让我们分解一下:
[a-z]
, \w
, \w+?
你的字符串是
abcde
比赛如下:
a b c d e
└─┘└─┘└─┘└─┘└─┘
会在匹配项之间留下的子字符串,所有这些都是空的。
上述三个正则表达式在这方面表现相同,因为它们只匹配单个字符。 \w+?
会这样做,因为它没有任何其他约束可能会使+?
尝试匹配的不仅仅是最低限度(毕竟它是懒惰的)。
<强> \w*?
强>
a b c d e
└┘ └┘ └┘ └┘ └┘ └┘
在这种情况下,匹配是在字符之间,留下以下子字符串:
"", "a", "b", "c", "d", "e", ""
然而,Java抛出了空尾的那个。
答案 1 :(得分: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)
尝试这些示例,您应该会看到所有空字符串。
答案 2 :(得分:1)
String.split
会在模式的每个匹配项处剪切字符串:
此方法返回的数组包含此字符串的每个子字符串,该子字符串由与给定表达式匹配的另一个子字符串终止,或者以字符串的结尾终止。
因此,只要匹配[a-z]
之类的模式,就会在该匹配时剪切字符串。由于字符串中的每个字符都与模式匹配,因此结果数组为空(删除尾随空字符串)。
同样适用于\w
和\w+?
(一个或多个\w
,但重复次数尽可能少)。那个\w*?
导致你期望的是*?
量词所导致的东西,因为如果可能的话,它会匹配零重复,所以一个空字符串。并且在给定字符串中的每个位置都找到一个空字符串。