简体   繁体   中英

String manipulation: How to replace a string with a specific pattern

I've a question here related to string manipulation based on a specific pattern. I am trying to replace a specific pattern with a pre-defined pattern using C#

For eg:

Scenario # 1

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

where this string could be used within linq's Where clause.

My sol:

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("')", "\")");

But this works only for the above scenario. I would like to generalize it for all teh below scenario's.

Scenario's:

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')

Any help would be appreciated. Thanks so much in advance!!

Final Solution:

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

Here's some sample code that seems to work:

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}')");

Note that I added tolerance for some internal whitespace and made assumptions about the text to be matched. What kinds of characters can be included inside the quotes and/or property identifiers? This may need to be tweaked to fit those requirements.

EDIT: I did some proactive tweaking. Changing \\w* to [^']* means it will match spaces or symbols or whatever until it reaches a closing quote, then stop matching. This is a little more in line with standard programming languages. The property name is kept more restrictive: \\w will match letters, numbers, and underscore characters. None of this is a substitute for a proper parser/lexer to catch errors and identify them explicitly, but it might do in a pinch.

EDIT 2: Updated to remove the requirement for brackets. Note that this is very tolerant: the pattern will match odd strings like substringof('xxxx', [[Property3]morestuffhere[) because it just assumes that [ and ] are valid characters in your identifier. It will not allow symbols or spaces, regardless of whether there are brackets or not. Note that the replacement string has also changed. If you don't remove the square brackets (as I have done in the sample), you could end up with double brackets.

It's hard to tell from your question what is changing and what is staying. Assuming that

  1. substringof does change (and can be any alphanumeric identifier),
  2. 'xxxx' does change but is always enclosed in single quotes,
  3. [Property2] does change (and does not have to be in square brackets),

here is some sample code to get you on your way:

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 that demonstrates this code. The output is:

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

Of course you need to go ahead and change the hardcoded replacement of substringof to Contains with whatever you're doing with your dictionary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM