使用锯齿状数组中的Regex将第一列值替换为第二列值

时间:2015-12-30 02:24:11

标签: c# regex jagged-arrays

在输入字符串中,我想使用以下Jagged Array将第一列值替换为前缀为\的第二列。例如,a<=bTestc<e变为a\lebTestc\lte。我怎样才能实现以编程方式?我正在使用下面定义的正则表达式模式,通过连接锯齿状数组的所有第一列元素,使用每个元素之间的|(正则表达式“OR”)分隔符。我通过将元素按最大长度的顺序连接到最短的长度来连接元素,这样如果较短的元素包含在较大的元素中,它就不会被替换[参考:Example。我正在使用.NET 4.5.2

string[][] sSymb = { new string[] { "!=", "ne" }, new string[] { "lt=", "leq" }, new string[] { "<", "lt" }, new string[] { ">", "gt" }, new string[] { "<=", "le" }, new string[] { "gt=", "geq" }, new string[] { ">=", "ge" }, new string[] { "!in", "notin" }, new string[] { "sub", "subset" }, new string[] { "sup", "supset" } };
string sPattern = "gt=|!in|sub|sup|!=|<=|lt|>=|<|>";
Regex regex = new Regex(sPattern);
string st = regex.Replace("a<=bcd<e", "\\$&"); //this prepends the first column element of array with \ . I need to replace the first column element with \ + second column element 
Console.WriteLine(st);

1 个答案:

答案 0 :(得分:1)

实现这一目标的最简单方法是使用overload for replace which allows you to pass in a match evaluator

string st = regex.Replace("a<=bcd<e", match =>
{
    var matchingSymbol = sSymb.FirstOrDefault(symbol => symbol[0] == match.Value);
    if (matchingSymbol == null)
        throw new Exception("Could not find symbol to exchange.");

    return string.Concat("\\",  matchingSymbol[1]);
});

另外 - 你必须使用锯齿状阵列吗?使用字典会容易得多。

修改:只需再看一下你要匹配的钥匙,就会发现订单在这里非常重要。您需要确保要更换的条目是从最具体到最不具体的顺序排序(否则正则表达式引擎将匹配&#34;&lt;&#34;当它可能匹配&#34;&lt; =&#34;。)

在这种情况下,有序词典可能是实现这一目标的最佳方式:

var sSymb = new System.Collections.Specialized.OrderedDictionary
{
    { "<=", "le" },
    { ">=", "ge" },
    { "!=", "ne" },
    { "<", "lt" },
    { ">", "gt" },
    { "gt=", "geq" }, 
    { "lt=", "leq" },
    { "!in", "notin" }, 
    { "sub", "subset" }, 
    { "sup", "supset" } 
};

var sPattern = sSymb.Keys
    .Cast<string>()
    .Aggregate((left, right) => string.Format("{0}|{1}", left, right));

Regex regex = new Regex(sPattern);
string st = regex.Replace("a<=bcd<e", match => string.Format("\\{0}", sSymb[match.Value]));
Console.WriteLine(st);