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

Posted

技术标签:

【中文标题】字符串操作:如何用特定模式替换字符串【英文标题】:String manipulation: How to replace a string with a specific pattern 【发布时间】:2013-05-04 01:52:18 【问题描述】:

我有一个关于基于特定模式的字符串操作的问题。我正在尝试使用 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\")");

【问题讨论】:

你从哪里得到 substringof 方法?还是您正在尝试创建的方法? 这看起来像是一个正则表达式替换的工作。你试过了吗? 我正在从 Kendo 网格中获取 substringof,并将其传递到 LINQ 的 WHERE 子句中,我必须将其转换为包含。还没有尝试过正则表达式。 【参考方案1】:

以下是一些似乎可行的示例代码:

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[) 这样的奇数字符串,因为它只是假设 [ 和 ] 是标识符中的有效字符。无论是否有括号,它都不允许符号或空格。 请注意,替换字符串也已更改。如果你不删除方括号(就像我在示例中所做的那样),你最终可能会得到双括号。

【讨论】:

谢谢 Dominic,我已经开始测试了.. 会告诉你进展如何。 嘿 Dominic,不知道为什么,但是 replaceRegex.Replace(input1, "[$pname].Contains('$text')") 不会用包含模式替换匹配的 RegEx 模式。代码对我来说看起来不错,但通过调试它我发现输出与输入相同。有什么想法吗?我错过了什么吗? 这是我在代码中使用的:Regex replaceRegex = new Regex("substringof\('(?[^']*)',\\s*\[( ?\\w+)\]\)"); inputStr = replaceRegex.Replace(inputStr , "[$pname].Contains('$text')"); 所有反斜杠都应该是双反斜杠。你就是这样吗?另外,你能给出具体的意见吗?该模式可能没有涵盖您在实际数据中拥有的所有字符类。我提供的代码已经过测试和验证,可以产生预期的输出,但那是使用带有“xxxx”的样本。 是的。我有双反斜杠。好的,例如: (Id > 0 and substringof('2', Name)) 。预期:(Id > 0 和 Name.Contains('2'))【参考方案2】:

很难从您的问题中看出什么在变化,什么在保持不变。假设

    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;
    

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,使用您对字典所做的任何操作。

【讨论】:

嗨 acheong,感谢您的回复。我也会试试这个解决方案。

以上是关于字符串操作:如何用特定模式替换字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何用python查找和替换json文件中的特定字符串

如何用regexp_replace在mysql中用特定字符替换多个字符?

如何用元组列表替换列表中正则表达式匹配的模式?

如何用相同长度的唯一数字替换特定长度的字符

如何用模式(正则表达式)替换字符串的一部分在数据框中抛出行

Netezza SQL - 如何用条件替换两个逗号之间的字符串