C# 替换为正则表达式

本文关键字:正则表达式 替换 | 更新日期: 2023-09-27 18:34:01

我是VB,C#的新手,并且正在努力解决正则表达式。我想我有以下代码格式将正则表达式匹配替换为文件中的空格。

编辑:根据评论,此代码块已更改。

var fileContents = System.IO.File.ReadAllText(@"C:'path'to'file.csv");

fileContents = fileContent.Replace(fileContent, @"regex", "(;

regex = new Regex(pattern);
regex.Replace(filecontents, "");
System.IO.File.WriteAllText(@"C:'path'to'file.csv", fileContents);

我的文件格式如下:

"1111111","22222222222","Text that may, have a comma, or two","2014-09-01",,,,,,

到目前为止,我已经正则表达式找到了 ,"", 之间包含逗号的任何字符串(第一个或最后一个单元格中永远不会有逗号,所以我不担心排除这两个。我正在 Expresso 中测试正则表达式

(?<=,")([^"]+,[^"]+)(?=",)

我只是不确定如何将该逗号隔离为需要替换的内容。最好的方法是什么?

解决:组合 [^"]+ 与后视/前瞻:

(?<=,"[^"]+)(,)(?=[^"]+",)

最终编辑:这是我最终的完整解决方案:

//read file contents
var fileContents = System.IO.File.ReadAllText(@"C:'path'to'file.csv");
//find all commas between double quotes
var regex = new Regex("(?<=,'")([^'"]+,[^'"]+(?='",)");
//replace all commas with ""
fileContents = regex.Replace(fileContents, m => m.ToString().Replace(",", ""));
//write result back to file
System.IO.File.WriteAllText(@"C:'path'to'file.csv", fileContents);

C# 替换为正则表达式

通过将 [^"]+ 与向前看?=和向后看?<=相结合来弄清楚,以便它找到以 ,"[anything that's not double quotes, one or more times] 开头的字符串,然后有一个逗号,然后以 [anything that's not double quotes, one or more times]", 结尾

(?<=,"[^"]+((,((?=[^"]+",(

尝试用这个解析出所有列:

 Regex regex = new Regex("(?<='").*?(?='")");

然后你可以做:

 foreach(Match match in regex.Matches(filecontents))
 {
      fileContents = fileContents.Replace(match.ToString(), match.ToString().Replace(",",string.Empty))
 }

可能没有那么快,但应该可以工作。

我可能会使用 Regex.Replace 的重载,它需要一个委托来返回替换的文本。当您有一个简单的正则表达式来识别模式,但您需要为替换做一些不太简单(复杂逻辑(的事情时,这很有用。

我发现保持正则表达式简单会在您以后尝试维护它们时带来好处。

注意:这类似于@Florian的答案,但此替换仅限于在匹配的文本中替换。

string exp = "(?<=,'")([^'"]+,[^'"]+)(?='",)";
var regex = new Regex(exp); 
string replacedtext = regex.Replace(filecontents, m => m.ToString().Replace(",",""))

你那里有一种不规则的语言。这是因为逗号可能意味着不同的东西,具体取决于它在文本流中的位置。奇怪的正则表达式旨在解析常规语言,其中逗号表示相同的内容,无论它在文本流中的哪个位置。不规则语言需要的是解析器。事实上,正则表达式主要用于在字符串输入解析器之前对字符串进行标记化。

虽然您尝试执行的操作可以使用正则表达式完成,但可能会非常慢。例如,您可以使用以下内容(即使逗号是字段中的第一个或最后一个字符,也可以使用(。但是,每次找到逗号时,它都必须前后扫描以检查它是否在两个引号字符之间。

 (?<=,"[^"]*),(?=[^"]*",)

另请注意,它们可能是您尚未发现的此方法中的缺陷。我不知道您是否有这个问题,但通常在 CSV 文件中,您可以在也可能有逗号的字段中使用引号字符。在这些情况下,像MS Excel这样的应用程序通常会将报价加倍,以表明它不是字段的结尾。喜欢这个:

"1111111","22222222222","Text that may, have a comma, Quote"" or two","2014-09-01",,,,,,

在这种情况下,您将不走运地使用正则表达式。

值得庆幸的是,处理CSV文件的代码非常简单:

    public static IList<string> ParseCSVLine(string csvLine)
    {
        List<string> result = new List<string>();
        StringBuilder buffer = new StringBuilder();
        bool inQuotes = false;
        char lastChar = ''0';
        foreach (char c in csvLine)
        {
            switch (c)
            {
                case '"':
                    if (inQuotes)
                    {
                        inQuotes = false;
                    }
                    else
                    {
                        if (lastChar == '"')
                        {
                            buffer.Append('"');
                        }
                        inQuotes = true;
                    }
                    break;
                case ',':
                    if (inQuotes)
                    {
                        buffer.Append(',');
                    }
                    else
                    {
                        result.Add(buffer.ToString());
                        buffer.Clear();
                    }
                    break;
                default:
                    buffer.Append(c);
                    break;
            }
            lastChar = c;
        }
        result.Add(buffer.ToString());
        buffer.Clear();
        return result;
    }

附言。CSV文件经常会遇到另外几个问题,我给出的代码无法解决。首先是,如果字段中间有一个行尾字符,会发生什么情况?其次是你怎么知道CSV文件是什么字符编码?这两个问题中的前者很容易通过稍微修改我的代码来解决。然而,如果不与提供文件的人达成某种协议,第二种几乎是不可能的。