4

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

2 回答 2

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

于 2013-05-09T15:06:58.957 回答
1

很难从您的问题中分辨出什么在变化,什么在保持不变。假如说

  1. substringof 确实发生了变化(并且可以是任何字母数字标识符),
  2. 'xxxx' 确实发生了变化,但总是用单引号括起来,
  3. [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;
    }
}

这是一个演示此代码的 Ideone 。输出是:

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

当然,您需要继续将硬编码的替换更改为substringofContains对字典所做的任何事情。

于 2013-05-09T15:18:04.470 回答