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

C# 字符串操作:如何用特定模式替换字符串,c#,string,string-matching,substring,C#,String,String Matching,Substring,我这里有一个关于基于特定模式的字符串操作的问题。我正在尝试使用C语言用预定义的模式替换特定的模式# 例如: 情景1 此字符串可在linq的where子句中使用 我的信: var key= myString.Substring(myString.Split(',')[0].Length + 1, myString.Length - myString.Split(',')[0].Length - 2); var value = myString.Replace("," + key, "").Repl

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

例如:

情景1

此字符串可在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]);

但这仅适用于上述场景。我想把它推广到下面的所有场景中

情景:

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}\")");
var replaceRegex=new Regex(“子字符串\\(\\s*”(?[^']*)\\s*,\\s*(?[\\w\\[\]]+)\\s*)”;
input=replaceRegex.Replace(输入,${pname}.Contains(\“${text}\”);

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

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}')");
System.Text.RegularExpressions.Regex replaceRegex=new System.Text.RegularExpressions.Regex(“子字符串\\(\\s*”(?[^']*)”\\s*,\\s*(?[\\w\\\[\]+)\\s*);
字符串输入1=“[Property1]==1234和子字符串('xxxx',[Property2])和子字符串('xx-xx',[Property3])”;
string input2=“substringof('xxxx',[Property2])和[Property1]==1234和substringof('xxxx',[Property3])”;
字符串input3=“(Id>0和子字符串('2',Name))”;
字符串output1=replaceRegex.Replace(input1,“${pname}.Contains(“${text}”)”);
字符串output2=replaceRegex.Replace(input2,“${pname}.Contains(“${text}”)”);
字符串output3=replaceRegex.Replace(input3,“${pname}.Contains(“${text}”)”);
请注意,我添加了一些内部空白的容差,并对要匹配的文本进行了假设。引号和/或属性标识符中可以包含哪些类型的字符?这可能需要调整以适应这些要求

编辑:我做了一些主动调整。将\w*更改为[^']*意味着它将匹配空格、符号或其他内容,直到到达结束引号,然后停止匹配。这更符合标准编程语言。属性名称的限制性更强:\w将匹配字母、数字和下划线字符。所有这些都不能替代适当的解析器/词法分析器来捕获错误并显式地识别它们,但在必要时它可能会这样做


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

很难从你的问题中分辨出什么在改变,什么在保留。假设

  • substringof
    会发生变化(可以是任何字母数字标识符)
  • 'xxxx'
    会发生变化,但总是用单引号括起来
  • [Property2]
    会发生变化(不必放在方括号内)
  • 以下是一些示例代码,可以帮助您上路:

    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;
        }
    }
    
    这演示了此代码。输出为:

    [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
    ,无论您在使用词典做什么。

    substringof方法是从哪里获得的?还是您试图创建的方法?这看起来像是正则表达式替换的工作。您尝试过吗还有吗?我正在从剑道网格中获取substringof,为了将其传递到LINQ的WHERE cluase,我必须将其转换为Contains。还没有尝试过正则表达式。感谢Dominic,我已经开始测试..将让您知道它是如何运行的。嘿Dominic,不确定为什么,但要替换regex.Replace(input1,[${pname}]。Contains('${text}'))没有用Contains模式替换匹配的正则表达式模式。代码看起来不错,但通过调试,我发现输出与输入相同。有什么想法吗?我遗漏了什么吗?这就是我在代码中使用的:RegEx replaceRegex=new RegEx(“substringof\('(?[^']*),\\s*\[(?\\w+\]\);inputStr=replaceRegex.Replace(inputStr,[${pname}].包含(“${text}”));所有的反斜杠都应该是双反斜杠。你是这样做的吗?另外,你能给出具体的输入吗?有可能模式没有涵盖实际数据中的所有字符类。我提供的代码经过测试和验证以产生预期的输出,但这是使用带有“xxxx”的示例。是的。I've双反斜杠。好的,例如:(Id>0和子字符串('2',Name))。预期:(Id>0和Name.Contains('2'))你好,阿琼,谢谢你的回答。我也会尝试这个解决方案。
    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;
        }
    }
    
    [Property2].Contains('xxxx')
    [Property1] == 1234 and [Property2].Contains('xxxx') and [Property3].Contains('xxxx')
    [Property2].Contains('xxxx') and [Property1] == 1234 and [Property3].Contains('xxxx')