字符串正则表达式拆分打印输出包含的行数少于预期?

时间:2015-01-23 10:56:30

标签: java regex string split

我们有以下代码

String quote = "aba*abaa**aabaa***";
String[] words = quote.split("a\\**");
for (String word : words) {
  System.out.println(word);
}

正则表达式恰好表示一个'a'字符,后跟零个或多个'*'字符

这意味着该字符串被标记为如下:a,b,a *,a,b,a,a **,a,a,b,a,a ***(这也可以使用双重检查模式/匹配类)

但是,上面的System.out.println()正在生成以下打印输出:(空行),b,(空行),b,(3个空行),b

这里不清楚,为什么第一个和第二个'b'之间只有一个空行(中间有两个令牌),为什么第二个和第三个'b'之间有三个空行(有四个)中间的代币)?

2 个答案:

答案 0 :(得分:2)

在第一个和第二个b之间,我们有ba*ab。分割方法中使用的分隔符模式将匹配a*,后跟空字符串,然后匹配a后跟b。空字符串由System.out.println()显示为空行。

同样,在第二个和第三个b之间,子字符串是baa**aab。因此,分隔符匹配a,然后是空字符串,然后a**后跟另一个空字符串,然后是a后跟第三个空字符串,最后是另一个ab。因此,总行数为3。

ba          a**           a              ab
     ^^^           ^^^           ^^^
  emptystring   emptystring   emptystring

为了获得指定的列表a, b, a*, a, b, a, a**, a, a, b, a, a***,一种解决方案是使用Matcher构建列表:

String quote = "aba*abaa**aabaa***";    
Pattern pattern = Pattern.compile("a\\**");
Matcher matcher = pattern.matcher(quote);
List<String> words = new ArrayList<String>();
int start = 0;
while(matcher.find()) {
    if(start < matcher.start()) {
        words.add(quote.substring(start, matcher.start()));
    }
    words.add(matcher.group());
    start = matcher.end();
}

答案 1 :(得分:1)

如果有k tokes,则应该有k - 1个空行,因此它按预期工作。我们来看一个例子:ba*ab,它被标记为b, a*, a, b。两个分隔符之间只有一个东西,所以它只给出一个空字符串。