我需要一个非常快的字符串拆分函数,它会拆分逗号分隔的字符串,而不会拆分包含逗号的双引号中的字符串。有没有这样做的功能?如果最好通过正则表达式处理,请指出必要的模式,如果适用,请告诉我任何我应该了解的速度优化提示。例如,如果有一种方法以这样的方式调用正则表达式,即不需要每次都重新评估正则表达式模式,等等。此函数将在短时间内被调用数千次。
注意,我确实在SO上看到了正则表达式帖子,如下所示:
Regular Expression To Split On Comma Except If Quoted
但它们是C#和其他语言,而不是Java。此外,如果有一个非正则表达式方法更快,我想知道它,如上所述。
- roschler
答案 0 :(得分:6)
听起来您正在尝试解析CSV格式的字符串/文件?
如果是这样,也许您不必自己编写代码。检查apache commons库以进行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)
答案 3 :(得分:0)
在commons-lang库中也有StrTokenizer:
StrTokenizer tokenizer = StrTokenizer.getCSVInstance();
tokenizer.reset(input);
String tokens[] = tokenizer.getTokenArray();
还有一种方法可以将令牌作为列表获取,它实现了Iterator / ListIterator函数,因此您可以在循环中以迭代器样式使用它。
您还可以继续调用“reset”方法来清除实例,并解析新的输入数据。
需要注意的一点是OpenCSV单词带有Reader实例,并将分析多行。此类使用字符串或char数组,并且只解析单个记录。它确实有一些内存开销,因为当你要求第一个令牌时,所有的解析都是在前面完成的。
然而,它比OpenCSV更具可配置性。
披露:我将此类的原始版本贡献给了库。