4

ここで、特定のパターンに基づく文字列操作に関連する質問があります。C# を使用して、特定のパターンを定義済みのパターンに置き換えようとしています。

例:

シナリオ 1

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

Whereこの文字列は、linq の句内で使用できます。

私のソル:

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

もちろん、先に進んでハードコードされた to の置換を、辞書で行っているものに変更する必要がありsubstringofますContains

于 2013-05-09T15:18:04.470 に答える