真正快速的Java函数来分割字符串而不影响引用的字符串?

时间:2011-07-10 00:33:18

标签: java regex performance split tokenize

我需要一个非常快的字符串拆分函数,它会拆分逗号分隔的字符串,而不会拆分包含逗号的双引号中的字符串。有没有这样做的功能?如果最好通过正则表达式处理,请指出必要的模式,如果适用,请告诉我任何我应该了解的速度优化提示。例如,如果有一种方法以这样的方式调用正则表达式,即不需要每次都重新评估正则表达式模式,等等。此函数将在短时间内被调用数千次。

注意,我确实在SO上看到了正则表达式帖子,如下所示:

Regular Expression To Split On Comma Except If Quoted

但它们是C#和其他语言,而不是Java。此外,如果有一个非正则表达式方法更快,我想知道它,如上所述。

- roschler

4 个答案:

答案 0 :(得分:6)

听起来您正在尝试解析CSV格式的字符串/文件?

如果是这样,也许您不必自己编写代码。检查apache commons库以进行CSV解析:

http://commons.apache.org/sandbox/csv/

答案 1 :(得分:2)

您基本上可以从链接的问题中删除C#代码,但是您需要撤消它的迭代器内容,将yield return替换为附加到列表:

public static List<String> SplitCSV(String csvString)
    StringBuilder sb = new StringBuilder();
    boolean quoted = false;

    List<String> list = new ArrayList<String>();

    for(char c : csvString.toCharArray()) {
        if (quoted) {
            if (c == '"')
                quoted = false;
            else
                sb.append(c);
        } else {
            if (c == '"') {
                quoted = true;
            } else if (c == ',') {
                list.add(sb.toString());
                sb = new StringBuilder();
            } else {
                sb.append(c);
            }
        }
    }

    if (quoted)
        throw new IllegalArgumentException("csvString: Unterminated quotation mark.");

    list.add(sb.toString());
    return list;
}

请注意,这当然不会处理带引号的字符串中的转义引号...

答案 2 :(得分:1)

我认为最流行的Java库自然是supercsvopencsv。您在寻找非库解决方案吗?

答案 3 :(得分:0)

在commons-lang库中也有StrTokenizer:

StrTokenizer tokenizer = StrTokenizer.getCSVInstance();
tokenizer.reset(input);
String tokens[] = tokenizer.getTokenArray();

还有一种方法可以将令牌作为列表获取,它实现了Iterator / ListIterator函数,因此您可以在循环中以迭代器样式使用它。

您还可以继续调用“reset”方法来清除实例,并解析新的输入数据。

需要注意的一点是OpenCSV单词带有Reader实例,并将分析多行。此类使用字符串或char数组,并且只解析单个记录。它确实有一些内存开销,因为当你要求第一个令牌时,所有的解析都是在前面完成的。

然而,它比OpenCSV更具可配置性。

披露:我将此类的原始版本贡献给了库。