正则表达式 - 如何删除“和”之间的逗号?

时间:2011-03-05 05:52:23

标签: c# regex

如何删除(逗号)在“(双反号逗号)和”(双反转逗号)之间。就像有"a","b","c","d,d","e","f"然后从这里开始,在“和”之间有一个逗号应该删除,在删除逗号之后它应该是"a","b","c","dd","e","f"在C#中的正则表达式的帮助下?

编辑:我忘了指定像"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

6 个答案:

答案 0 :(得分:10)

假设输入与示例一样简单(即,不是完整的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,b,c,"d,d,d",e,f,"g,g",h
a,b,c,"ddd",e,f,"gg",h

正则表达式匹配任何后跟奇数引号的逗号。


编辑:如果使用撇号(')而不是引号(")引用字段,则技术完全相同 - 除非您不必转义引号:< / p>

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" Nails'(原文如此)或"Kelly's Heroes"。这将我们带入成熟的CSV领域(如果不是超越),我们已经确定我们不会去那里。 :d

答案 1 :(得分:5)

出于某种原因,它们被称为正则表达式 - 它们用于处理符合“常规”内容的非常具体和学术定义的字符串。看起来你在这里有一些相当典型的csv数据,而且csv字符串超出了那个特定的定义: csv数据不是正式的“常规”。

尽管如此,仍然可以使用正则表达式来处理csv数据。但是,要这样做,您必须使用常规正则表达式的某些扩展来使它们完全图像化,知道某些特定csv数据的约束,这些约束在一般情况下是未承诺的,或者两者都有。无论哪种方式,执行此操作所需的表达式都非常难以管理。即使有可能,这通常也不是一个好主意。

更好(通常更快)的解决方案是使用专用的CSV解析器。在代码项目(FastCSV和Linq-to-CSV)中托管了两个好的,在.Net Framework(Microsoft.VisualBasic.TextFieldParser)中内置了一个(实际上有几个),我有一个here on Stack Overflow。除了基于正则表达式的解决方案之外,其中任何一个都会表现得更好,而且工作效果更好。

请注意,我并不认为它无法完成。今天大多数正则表达式引擎都有必要的扩展来实现这一点,并且大多数解析csv数据的人都对数据有足够的了解他们正在处理以适当地约束它。我认为执行起来较慢,难以实现,难以维护,并且与专用解析器替代方案相比更容易出错,这可能构建在您正在使用的任何平台上,因此不符合您的最佳利益。

答案 2 :(得分:1)

您可以使用:

var result = Regex.Replace(yourString, "([a-z]),", "$1");

很抱歉,在看到您的修改后,正则表达式不适用于此。

答案 3 :(得分: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是否是您想要使用的内容。

答案 4 :(得分:1)

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

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);

如果您需要单引号,请使用单个""替换模式中的所有'

答案 5 :(得分:-1)

或许像以下那样?

(,)