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

gab6jxml  于 2023-05-08  发布在  其他
关注(0)|答案(5)|浏览(199)

我在逗号分隔的文件中有一个以下格式的字符串:

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

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

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

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

r3i60tvu

r3i60tvu1#

就我个人而言,我会避免在这里使用正则表达式-假设没有嵌套的引号,这很容易写成一个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]);
    }
}
jc3wubiy

jc3wubiy2#

这种类型的问题是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 parser来解析字符串,然后用替换的列再次写入。

mec1mxoz

mec1mxoz3#

下面是如何使用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));
xxls0lw8

xxls0lw84#

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

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

在这种情况下,正则表达式的问题是它不会捕获“this,has,two commas”。

kzipqqlq

kzipqqlq5#

你能给予这个吗:“[\w ],[\w ]”(包括双引号)?要小心替换,因为直接替换将删除双引号中的整个字符串。

相关问题