栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

为什么在Java 8中,split有时会删除结果数组开头的空字符串?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

为什么在Java 8中,split有时会删除结果数组开头的空字符串?

String.split
(调用
Pattern.split
)的行为在Java 7和Java 8之间改变。

文献资料

Pattern.split
在Java 7和Java 8的文档之间进行比较,我们观察到添加了以下子句:

如果在输入序列的开头存在一个正宽匹配,则在结果数组的开头将包含一个空的前导子字符串。开头的零宽度匹配永远不会产生这样的空前导子字符串。

与Java 7相比

String.split
,Java 8中还添加了相同的子句。

参考实施

让我们比较一下

Pattern.split
Java 7和Java 8中的参考实现的代码。该代码是从greppre检索的,用于版本7u40-b43和8-b132。

Java 7

public String[] split(CharSequence input, int limit) {    int index = 0;    boolean matchLimited = limit > 0;    ArrayList<String> matchList = new ArrayList<>();    Matcher m = matcher(input);    // Add segments before each match found    while(m.find()) {        if (!matchLimited || matchList.size() < limit - 1) { String match = input.subSequence(index, m.start()).toString(); matchList.add(match); index = m.end();        } else if (matchList.size() == limit - 1) { // last one String match = input.subSequence(index, input.length()).toString(); matchList.add(match); index = m.end();        }    }    // If no match was found, return this    if (index == 0)        return new String[] {input.toString()};    // Add remaining segment    if (!matchLimited || matchList.size() < limit)        matchList.add(input.subSequence(index, input.length()).toString());    // Construct result    int resultSize = matchList.size();    if (limit == 0)        while (resultSize > 0 && matchList.get(resultSize-1).equals("")) resultSize--;    String[] result = new String[resultSize];    return matchList.subList(0, resultSize).toArray(result);}

Java 8

public String[] split(CharSequence input, int limit) {    int index = 0;    boolean matchLimited = limit > 0;    ArrayList<String> matchList = new ArrayList<>();    Matcher m = matcher(input);    // Add segments before each match found    while(m.find()) {        if (!matchLimited || matchList.size() < limit - 1) { if (index == 0 && index == m.start() && m.start() == m.end()) {     // no empty leading substring included for zero-width match     // at the beginning of the input char sequence.     continue; } String match = input.subSequence(index, m.start()).toString(); matchList.add(match); index = m.end();        } else if (matchList.size() == limit - 1) { // last one String match = input.subSequence(index, input.length()).toString(); matchList.add(match); index = m.end();        }    }    // If no match was found, return this    if (index == 0)        return new String[] {input.toString()};    // Add remaining segment    if (!matchLimited || matchList.size() < limit)        matchList.add(input.subSequence(index, input.length()).toString());    // Construct result    int resultSize = matchList.size();    if (limit == 0)        while (resultSize > 0 && matchList.get(resultSize-1).equals("")) resultSize--;    String[] result = new String[resultSize];    return matchList.subList(0, resultSize).toArray(result);}

Java 8中以下代码的添加排除了输入字符串开头的零长度匹配,这解释了上面的行为。

 if (index == 0 && index == m.start() && m.start() == m.end()) {     // no empty leading substring included for zero-width match     // at the beginning of the input char sequence.     continue; }

保持兼容性

Java 8及更高版本中的以下行为

为了使make

split
在各个版本中的行为保持一致并与Java 8中的行为兼容:

  1. 如果你的正则表达式可以匹配零长度字符串,则只需
    (?!A)
    在正则表达式的末尾添加,然后将原始正则表达式包装在非捕获组中即可
    (?:...)
    (如有必要)。
  2. 如果你的正则表达式不能匹配零长度字符串,则无需执行任何操作。
  3. 如果你不知道正则表达式是否可以匹配零长度字符串,请执行步骤1中的两个操作。
    (?!A)
    检查字符串是否不以字符串开头结尾,这意味着匹配在字符串开头为空匹配。

Java 7及更高版本中的以下行为

没有通用的解决方案可以使它

split
与Java 7及更低版本向后兼容,除非替换所有实例
split
以指向你自己的自定义实现。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/370802.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号