使用正则表达式进行替换模式查找

本文关键字:替换 模式 查找 正则表达式 | 更新日期: 2023-09-27 18:03:02

在逗号分隔的文件中有如下格式的字符串:

someText, "Text with, delimiter", moreText, "Text Again"

我需要做的是创建一个方法,该方法将查看字符串,并将用美元符号($)替换引号文本中的任何逗号。

方法之后,字符串将是:

someText, "Text with$ delimiter", moreText, "Text Again"

我不完全擅长RegEx,但想知道如何使用正则表达式来搜索模式(在引号之间找到逗号),然后用美元符号替换该逗号。

使用正则表达式进行替换模式查找

就我个人而言,我会避免这里的正则表达式-假设没有嵌套引号,这是相当简单的编写为for循环,我认为这将更有效:

var inQuotes = false;
var sb = new StringBuilder(someText.Length);
for (var i = 0; i < someText.Length; ++i)
{
    if (someText[i] == '"')
    {
        inQuotes = !inQuotes;
    }
    if (inQuotes && someText[i] == ',')
    {
        sb.Append('$');
    }
    else
    {
        sb.Append(someText[i]);
    }
}

这种类型的问题是Regex失败的地方,这样做:

    var sb = new StringBuilder(str);
    var insideQuotes = false;
    for (var i = 0; i < sb.Length; i++)
    {
        switch (sb[i])
        {
            case '"':
                insideQuotes = !insideQuotes;
                break;
            case ',':
                if (insideQuotes)
                    sb.Replace(',', '$', i, 1);
                break;
        }               
    }
    str = sb.ToString();

您也可以使用CSV解析器解析字符串,然后用替换的列重新编写。

如何使用Regex.Replace:

        string output = Regex.Replace(
            input,
            "'".*?'"",
            m => m.ToString().Replace(',', '$'));

当然,如果您想忽略转义双引号,情况会变得更复杂。特别是当转义字符本身可以转义时。

假设转义字符是',那么在尝试匹配双引号时,您只需要匹配前面有偶数个转义字符(包括零)的引号。下面的模式将为您完成:

string pattern = @"(?<=((^|[^''])(''''){0,}))"".*?(?<=([^''](''''){0,}))""";

此时,您可能更愿意放弃正则表达式;)

更新:

在回复你的评论时,很容易对不同的引号、分隔符和占位符进行操作配置。

        string quote = "'"";
        string delimiter = ",";
        string placeholder = "$";
        string output = Regex.Replace(
            input,
            quote + ".*?" + quote,
            m => m.ToString().Replace(delimiter, placeholder));

如果你想走正则表达式路线,这里是你要找的:

var result = Regex.Replace( text, "('"[^,]*),([^,]*'")", "$1$$$2" );

在这种情况下,regex的问题是它不会捕获"this, has,两个逗号"

你能试试这个吗:"['w],['w]"(包括双引号)?并且要小心替换,因为直接替换将删除括在双引号中的整个字符串。