C#分割逗号分隔值
如何将逗号分隔的字符串与也可以包含逗号的带引号的字符串拆分 输入示例:C#分割逗号分隔值,c#,.net,regex,csv,C#,.net,Regex,Csv,如何将逗号分隔的字符串与也可以包含逗号的带引号的字符串拆分 输入示例: John, Doe, "Sid, Nency", Smith 预期产出: 约翰 母鹿 希德,内西 史密斯 用逗号分割是可以的,但我有一个要求,就是允许使用“Sid,Nency”这样的字符串。我尝试使用正则表达式来拆分这些值。Regex“,(?=([^\“]*\”[^\“]*\”*[^\“]*$)”来自Java问题,它对我的.NET代码不起作用。它将一些字符串加倍,查找额外结果等 那么分割这些字符串的最佳方法是什么呢?只
John, Doe, "Sid, Nency", Smith
预期产出:
- 约翰
- 母鹿
- 希德,内西
- 史密斯
“,(?=([^\“]*\”[^\“]*\”*[^\“]*$)”
来自Java问题,它对我的.NET代码不起作用。它将一些字符串加倍,查找额外结果等
那么分割这些字符串的最佳方法是什么呢?只需检查字符串即可。在检查字符串时,请跟踪
如果您是否处于“块”中。如果您处于-中,请不要将逗号视为
逗号(作为分隔符)。否则就这样处理。它是一个简单的
算法,我自己写。当你第一次遇到“你进入
一个街区。当你遇到“下一个”时,你就结束了你的障碍,依此类推。
因此,只需通过字符串一次即可完成此操作。
import java.util.ArrayList;
public class Test003 {
public static void main(String[] args) {
String s = " John, , , , \" Barry, John \" , , , , , Doe, \"Sid , Nency\", Smith ";
StringBuilder term = new StringBuilder();
boolean inQuote = false;
boolean inTerm = false;
ArrayList<String> terms = new ArrayList<String>();
for (int i=0; i<s.length(); i++){
char ch = s.charAt(i);
if (ch == ' '){
if (inQuote){
if (!inTerm) {
inTerm = true;
}
term.append(ch);
}
else {
if (inTerm){
terms.add(term.toString());
term.setLength(0);
inTerm = false;
}
}
}else if (ch== '"'){
term.append(ch); // comment this out if you don't need it
if (!inTerm){
inTerm = true;
}
inQuote = !inQuote;
}else if (ch == ','){
if (inQuote){
if (!inTerm){
inTerm = true;
}
term.append(ch);
}else{
if (inTerm){
terms.add(term.toString());
term.setLength(0);
inTerm = false;
}
}
}else{
if (!inTerm){
inTerm = true;
}
term.append(ch);
}
}
if (inTerm){
terms.add(term.toString());
}
for (String t : terms){
System.out.println("|" + t + "|");
}
}
}
import java.util.ArrayList;
公共类Test003{
公共静态void main(字符串[]args){
字符串s=“John,,\“Barry,John\”,,Doe,\“Sid,Nency\”,Smith”;
StringBuilder术语=新的StringBuilder();
布尔inQuote=false;
布尔中间值=假;
ArrayList terms=新的ArrayList();
对于(int i=0;i这是因为捕获组。只需将其转换为非捕获组:
",(?=(?:[^""]*""[^""]*"")*[^""]*$)"
^^
捕获组正在结果中包含捕获的部分
只需修剪结果。我在Csv解析器类中使用以下代码来实现这一点:
private string[] ParseLine(string line)
{
List<string> results = new List<string>();
bool inQuotes = false;
int index = 0;
StringBuilder currentValue = new StringBuilder(line.Length);
while (index < line.Length)
{
char c = line[index];
switch (c)
{
case '\"':
{
inQuotes = !inQuotes;
break;
}
default:
{
if (c == ',' && !inQuotes)
{
results.Add(currentValue.ToString());
currentValue.Clear();
}
else
currentValue.Append(c);
break;
}
}
++index;
}
results.Add(currentValue.ToString());
return results.ToArray();
} // eo ParseLine
private string[]ParseLine(字符串行)
{
列表结果=新列表();
bool-inQuotes=false;
int指数=0;
StringBuilder currentValue=新的StringBuilder(line.Length);
while(索引<行长度)
{
char c=行[索引];
开关(c)
{
案例“\”:
{
inQuotes=!inQuotes;
打破
}
违约:
{
如果(c==','&&&!引号)
{
results.Add(currentValue.ToString());
currentValue.Clear();
}
其他的
currentValue.Append(c);
打破
}
}
++指数;
}
results.Add(currentValue.ToString());
返回结果。ToArray();
}//eo解析线
如果您发现正则表达式太复杂,可以这样做:
string initialString = "John, Doe, \"Sid, Nency\", Smith";
IEnumerable<string> splitted = initialString.Split('"');
splitted = splitted.SelectMany((str, index) => index % 2 == 0 ? str.Split(',') : new[] { str });
splitted = splitted.Where(str => !string.IsNullOrWhiteSpace(str)).Select(str => str.Trim());
string initialString=“John,Doe,\“Sid,Nency\”,Smith”;
IEnumerable splitted=initialString.Split(“”);
splitted=splitted.SelectMany((str,index)=>index%2==0?str.Split(','):new[]{str});
splitted=splitted.Where(str=>!string.IsNullOrWhiteSpace(str)).Select(str=>str.Trim());
看起来您正在处理CSV输入?如果是这样,请使用CSV库-有很多好的库,这将为您节省很多痛苦!!如果不是,请澄清您的问题,解释为什么CSV库不合适…不,它不是CSV文档。它只是一个stringRB,如果您演示给我看,我将很高兴,我如何使用CSVLib处理这个问题的一种黑客方法是首先在“
之间拆分,然后通过,
拆分备用字符串(在获得的数组中)。这里的Perl解决方案(因为您将标记放回):@AndreiMikhalevich好的,我发布了一些代码作为说明。
string initialString = "John, Doe, \"Sid, Nency\", Smith";
IEnumerable<string> splitted = initialString.Split('"');
splitted = splitted.SelectMany((str, index) => index % 2 == 0 ? str.Split(',') : new[] { str });
splitted = splitted.Where(str => !string.IsNullOrWhiteSpace(str)).Select(str => str.Trim());