字符串操作:如何用特定模式替换字符串

时间:2013-05-09 14:32:52

标签: c# string string-matching substring

我在这里有一个基于特定模式的字符串操作问题。我正在尝试使用C#

用预定义的模式替换特定模式

例如:

情景#1

Input: substringof('xxxx', [Property2])
Output: [Property2].Contains('xxxx')

这个字符串可以在linq的Where子句中使用。

我的溶胶:

var key= myString.Substring(myString.Split(',')[0].Length + 1, myString.Length - myString.Split(',')[0].Length - 2);
var value = myString.Replace("," + key, "").Replace([Key from Dictionary], [Value from Dictionary]);

Expected string: key + '.' + value.Replace("('", "(\"").Replace("')", "\")");

但这仅适用于上述情况。我想在下面的场景中概括它。

情景的:

Input: [Property1] == 1234 and substringof('xxxx', [Property2]) and substringof('xxxx', [Property3])
Output: [Property1] == 1234 and [Property2].Contains('xxxx') and [Property3].Contains('xxxx')

Input: substringof('xxxx', [Property2]) and [Property1] == 1234 and substringof('xxxx', [Property3])
Output: [Property2].Contains('xxxx') and [Property1] == 1234  and [Property3].Contains('xxxx')

任何帮助将不胜感激。 非常感谢提前!!

最终解决方案:

var replaceRegex = new Regex("substringof\\(\\s*'(?<text>[^']*)'\\s*,\\s*(?<pname>[\\w\\[\\]]+)\\s*\\)");
input = replaceRegex.Replace(input, "${pname}.Contains(\"${text}\")");

2 个答案:

答案 0 :(得分:3)

以下是一些似乎有效的示例代码:

System.Text.RegularExpressions.Regex replaceRegex = new System.Text.RegularExpressions.Regex("substringof\\(\\s*'(?<text>[^']*)'\\s*,\\s*(?<pname>[\\w\\[\\]]+)\\s*\\)");

string input1 = "[Property1] == 1234 and substringof('xxxx', [Property2]) and substringof('xx xx', [Property3])";
string input2 = "substringof('xxxx', [Property2]) and [Property1] == 1234 and substringof('xxxx', [Property3])";
string input3 = "(Id > 0 and substringof('2', Name))";

string output1 = replaceRegex.Replace(input1, "${pname}.Contains('${text}')");
string output2 = replaceRegex.Replace(input2, "${pname}.Contains('${text}')");
string output3 = replaceRegex.Replace(input3, "${pname}.Contains('${text}')");

请注意,我为某些内部空格添加了容差,并对要匹配的文本进行了假设。引号和/或属性标识符中可以包含哪些字符?这可能需要调整以满足这些要求。

编辑:我做了一些主动调整。将\ w *更改为[^'] *表示它将匹配空格或符号或其他任何内容,直到达到结束引号,然后停止匹配。这与标准编程语言更加一致。属性名称限制性更强:\ w将匹配字母,数字和下划线字符。这些都不能替代正确的解析器/词法分析器来捕获错误并明确地识别它们,但它可能会在紧要关头。

编辑2:已更新以删除括号的要求。请注意,这是非常宽容的:模式将匹配像substringof('xxxx', [[Property3]morestuffhere[)这样的奇数字符串,因为它只是假设[和]是标识符中的有效字符。无论是否有括号,它都不允许使用符号或空格。 请注意,替换字符串也已更改。如果你不删除方括号(就像我在样本中所做的那样),你可能会得到双括号。

答案 1 :(得分:1)

很难从你的问题中看出改变的是什么以及留下什么。假设

  1. substringof 更改(可以是任何字母数字标识符),
  2. 'xxxx' 进行更改,但始终用单引号括起来,
  3. [Property2] 更改< 必须在方括号内),
  4. 这里有一些示例代码可以帮助您:

    using System;
    using System.Text.RegularExpressions;
    
    public class Test
    {
        public static void Main()
        {
            Console.WriteLine(Convert("substringof('xxxx', [Property2])"));
            Console.WriteLine(Convert("[Property1] == 1234 and substringof('xxxx', [Property2]) and substringof('xxxx', [Property3])"));
            Console.WriteLine(Convert("substringof('xxxx', [Property2]) and [Property1] == 1234 and substringof('xxxx', [Property3])"));
        }
    
        public static string Convert(string str)
        {
            Regex r = new Regex("(\\w+)\\(\\s*('[^']*')\\s*,\\s*([^)]+?)\\s*\\)");
            return r.Replace(str, new MatchEvaluator(MatchEvaluatorDelegate));
        }
    
        public static string MatchEvaluatorDelegate(Match m)
        {
            string answer = "";
            answer += m.Groups[3].Value + ".";
            answer += m.Groups[1].Value.Replace("substringof", "Contains");
            answer += "(" + m.Groups[2].Value + ")";
            return answer;
        }
    }
    

    Here is an Ideone演示了此代码。输出是:

    [Property2].Contains('xxxx')
    [Property1] == 1234 and [Property2].Contains('xxxx') and [Property3].Contains('xxxx')
    [Property2].Contains('xxxx') and [Property1] == 1234 and [Property3].Contains('xxxx')
    

    当然,您需要继续将substringof的硬编码替换更改为Contains,无论您使用字典做什么。