您可以从正则表达式开始:
[^",]*|"[^"]*"
它匹配不包含逗号的非引用字符串或引用字符串。但是,有很多问题,包括:
你输入的逗号后面真的有空格吗?或者,更一般地说,您是否允许不完全位于字段第一个字符的引号?
如何在包含引号的字段周围加上引号?
根据您回答该问题的方式,您最终可能会得到不同的正则表达式。(实际上,使用 CSV 解析库的习惯建议与其说是处理极端情况,不如说是不必考虑它们,因为您假设“标准 CSV”处理,无论根据解析库。CSV是一团糟。)
我成功使用的一个正则表达式(尽管它与CSV不兼容)是:
(?:[^",]|"[^"]*")*
这与第一个非常相似,除了它允许任意数量的连接字段,因此以下两个都被识别为单个字段:
"John"", Mary"
John", "Mary
CSV 标准将第一个视为代表:
John", Mary -- internal quote
并将第二个中的引号视为普通字符,从而产生两个字段。所以YMMV。
无论如何,一旦你决定了一个合适的正则表达式,算法就很简单了。使用伪代码,因为我远非 Java 专家。
repeat:
match the regex at the current position
and append the result to the result;
if the match fails:
report error
if the match goes to the end of the string:
done
if the next character is a ',':
advance the position by one
otherwise:
report error
根据正则表达式,您报告错误的两种情况可能不存在。通常,如果引用的字段没有终止,第一个将触发(并且您需要决定是否允许在引用的字段中换行 - CSV 会)。如果您使用我提供的第一个正则表达式,然后没有立即用逗号跟随带引号的字符串,则可能会发生第二个。