C# Regex如何删除介于“之间”的逗号;“和”;?

C# Regex如何删除介于“之间”的逗号;“和”;?,c#,regex,C#,Regex,如何删除介于“(双倒逗号)和“(双倒逗号)之间的(逗号)。比如有“a”、“b”、“c”、“d、d”、“e”、“f”,然后在“和”之间有一个逗号应该被删除,删除该逗号后,在c#中的正则表达式的帮助下,它应该是“a”、“b”、“c”、“dd”、“e”、“f” 编辑:我忘了指定引号之间可能有双逗号,例如“a”、“b”、“c”、“d、d、d”、“e”、“f”,因为正则表达式不起作用。引号之间可以有任意数量的逗号 可以有像a,b,c,“d,d”,e,f这样的字符串,然后应该有像a,b,c,dd,e,f这样

如何删除介于“(双倒逗号)和“(双倒逗号)之间的(逗号)。比如有
“a”、“b”、“c”、“d、d”、“e”、“f”
,然后在“和”之间有一个逗号应该被删除,删除该逗号后,在c#中的正则表达式的帮助下,它应该是
“a”、“b”、“c”、“dd”、“e”、“f”

编辑:我忘了指定引号之间可能有双逗号,例如
“a”、“b”、“c”、“d、d、d”、“e”、“f”
,因为正则表达式不起作用。引号之间可以有任意数量的逗号


可以有像
a,b,c,“d,d”,e,f这样的字符串,然后应该有像
a,b,c,dd,e,f这样的结果,如果像
a,b,c,“d,d,d”,e,f这样的字符串,那么结果应该像
a,b,c,ddd,e,f
可能是这样的吧

“(,)”

您可以使用:

var result = Regex.Replace(yourString, "([a-z]),", "$1");
很抱歉,看到您的编辑后,正则表达式不适用于此

var input = "\"a\",\"b\",\"c\",\"d,d\",\"e\",\"f\"";
var regex = new Regex("(\"\\w+),(\\w+\")");
var output = regex.Replace(input,"$1$2");
Console.WriteLine(output);

您需要评估
\w
是否是您想要使用的内容。

它们被称为正则表达式是有原因的-它们用于处理符合“正则”的非常具体和学术定义的字符串。看起来这里有一些相当典型的csv数据,而csv字符串恰好在特定定义之外:csv数据在形式上不是“常规”的

尽管如此,还是可以使用正则表达式来处理csv数据。但是,要做到这一点,您必须使用普通正则表达式的某些扩展,使其图灵完整,了解特定csv数据的某些约束条件,这些约束条件在一般情况下是不承诺的,或者两者兼而有之。无论哪种方式,执行此操作所需的表达式都很难处理。这通常不是一个好主意,即使是在可能的情况下

更好(通常更快)的解决方案是使用专用的CSV解析器。代码项目中有两个很好的版本(FastCSV和Linq to CSV),有一个(实际上有几个)内置在.Net框架中(Microsoft.VisualBasic.TextFieldParser),我有一个。其中任何一个都会比基于正则表达式的解决方案执行得更好,而且只是简单的工作


注意,我并不是说这是不可能的。如今,大多数正则表达式引擎都有必要的扩展来实现这一点,而且大多数解析csv数据的人都对他们正在处理的数据有足够的了解,可以对其进行适当的约束。我认为,与专用解析器相比,它的执行速度慢、实现难度大、维护难度大、更容易出错。专用解析器可能内置于您使用的任何平台中,因此不符合您的最佳利益。

假设输入与示例一样简单(即,不是完整的CSV数据),这应该做到:

string input = @"a,b,c,""d,d,d"",e,f,""g,g"",h";
Console.WriteLine(input);

string result = Regex.Replace(input,
    @",(?=[^""]*""(?:[^""]*""[^""]*"")*[^""]*$)",
    String.Empty);
Console.WriteLine(result);
输出: 如果某些字段用撇号引用,而其他字段用引号引用,则需要另一种方法


编辑:可能应该在前面的编辑中提到这一点,但是您可以将这两个正则表达式组合成一个正则表达式,该正则表达式将处理撇号或引号(但不能同时处理两个):


实际上,它将处理像
'a,a',“b,b”
这样的简单字符串。问题是,没有什么可以阻止您在另一种类型的引用字段中使用其中一个引用字符,如
'9“钉子”
(原文如此)或
“凯利的英雄”
。这将把我们带入一个成熟的CSV领域(如果没有超出),我们已经确定我们不会去那里。:D

使用Regex.Replace和回调应该非常简单:

string pattern = @"
""      # open quotes
[^""]*  # some not quotes
""      # closing quotes
";
data = Regex.Replace(data, pattern, m => m.Value.Replace(",", ""),
    RegexOptions.IgnorePatternWhitespace);
您甚至可以稍微修改以允许转义引号(这里我有
\“
,注释解释了如何使用

字符串模式=@”
\\.#转义字符(可选为“”)
|
(?
“”#开放式报价
(?:\\.[^”“])*#有些不是引号或转义字符
#另一种选择是(?:“|[^]”)*
“”#结束语
)
";
data=Regex.Replace(数据、模式、,
m=>m.Groups[“Quotes”].Success?m.Value.Replace(“,”,”):m.Value,
RegexOptions.ignorepattern(空格);

如果需要单引号,请替换所有
“”
在带有单个
的模式中,

是否可以匹配不带引号的逗号?这些项目都在一个字符串中吗?或者您使用的是一个数组或字符串列表,其中嵌入了逗号?@Orbit,它应该只匹配带引号的逗号。@finalized,这不是字符串数组。@Jon Freeland,它适用于问题中描述的字符串,但很抱歉,我忘了指定引号之间可能有双逗号,如“a”、“b”、“c”、“d、d”、“e”、“f”,因为正则表达式不起作用。引号之间可以有任意数量的逗号。@Jon Freeland,它不适用于“a”、“b”、“c”、“d、d、d”、“e”、“f”@Jon,但如果字符串类似于a,b,c,“d,d”,e,f,那么它将替换所有逗号。@Rebecca是正确的,原来正则表达式不适合这种情况。@Jon Freeland,那么有没有其他解决方案,比如可以有两个正则表达式来表示“a”,“b”,“c”,“d,d”,“e”,“f”和a,b,c,“d,d”,e,f?对于第一个字符串,您指定的正则表达式有效,对于第二种类型的字符串,是否还有其他正则表达式可以删除逗号?我们是否可以首先编辑第二个字符串,并通过在每个值a、b、c、d、d、e、f中添加“”使其与第一个字符串类似,从而使其成为“a”、“b”、“c”、“d、d”、“e”、“f”然后使用相同的正则表达式我们可以这样做吗?它适用于问题中描述的字符串,但很抱歉,我忘了指定引号之间可能有双逗号,如“a”、“b”、“c”、“d、d”、“e”、“f”因为正则表达式不起作用。引号之间可以有任意数量的逗号。@Harikrishna,你还忘了什么其他要求吗?非常抱歉,我
string input = @"a,b,c,'d,d,d',e,f,'g,g',h";
Console.WriteLine(input);

string result = Regex.Replace(input,
    @",(?=[^']*'(?:[^']*'[^']*')*[^']*$)",
    String.Empty);
Console.WriteLine(result);
@",(?=[^']*'(?:[^']*'[^']*')*[^']*$|[^""]*""(?:[^""]*""[^""]*"")*[^""]*$)"
string pattern = @"
""      # open quotes
[^""]*  # some not quotes
""      # closing quotes
";
data = Regex.Replace(data, pattern, m => m.Value.Replace(",", ""),
    RegexOptions.IgnorePatternWhitespace);
string pattern = @"
\\.     # escaped character (alternative is be """")
|
(?<Quotes>
    ""              # open quotes
    (?:\\.|[^""])*  # some not quotes or escaped characters
                      # the alternative is (?:""""|[^""])*
    ""              # closing quotes
)
";
data = Regex.Replace(data, pattern,
            m => m.Groups["Quotes"].Success ? m.Value.Replace(",", "") : m.Value,
            RegexOptions.IgnorePatternWhitespace);