Я пытаюсь разобрать имя функции и ее параметры, чтобы обновить содержимое строки. Я храню вызов функции в строке, и прежде чем вызывать его, мне нужно изменить его, а затем вызвать. Ниже приведена строка, содержащая функцию.

var expression = "AreEqual  ( \"test\" ,  Obj.Prop ) && AreEqual ( 1 , 2 ) && AREeQuAl( Obj.Prop , 1 )&& AreEqual (\"\\\"\\\",\" , 2 ) AND AreEqual (',' , ',' ) AreEqual ( \"A,B\" , Obj.Prop ) ";

var expectedOutPut = "MyClass.AreEqual( new (\"test\" AS A) , new ( Obj.Prop AS A) ) && MyClass.AreEqual ( new( 1 AS A ), new ( 2 AS A) ) && MyClass.AREeQuAl( new (Obj.Prop AS A) , new ( 1 AS A) ) && MyClass.AreEqual (new ( \"\\\"\\\",\" AS A) , new ( 2 AS A)  ) && MyClass.AreEqual (new (',' AS A) , new( ',' AS A )) && MyClass.AreEqual ( new (\"A,B\" AS A) ,new ( Obj.Prop AS A) )";

Я пытался следовать регулярному выражению, но оно разрывается в правильных запятых внутри двойных кавычек.

@"(AreEqual.*?\()\s*([^,]+?)\s*(?=,|$)"

using System;
using System.Text.RegularExpressions;

public class Program
{
    public static void Main()
    {
        string pattern = @"(AreEqual.*?\()\s*([^,]+?)\s*(?=,|$)";
        string input = @"AreEqual  ( ""test"" ,  Obj.Prop ) && AreEqual ( 1 , 2 ) && AREeQuAl( Obj.Prop , 1 )&& AreEqual (""\""\"","" , 2 ) AND AreEqual (',' , ',' ) AreEqual ( ""A,B"" , Obj.Prop )";

        RegexOptions options = RegexOptions.Multiline | RegexOptions.IgnoreCase;

        foreach (Match m in Regex.Matches(input, pattern, options))
        {
            Console.WriteLine("'{0}' found at index {1}.", m.Value, m.Index);
        }
        Console.ReadLine();
    }
}
1
Mahesh Jadhav 12 Апр 2019 в 07:41

2 ответа

Лучший ответ

Я попытался сопоставить элементы в группы, а затем отформатировать новую строку, используя эти группы.

string pattern = @"(AreEqual)\s*\((\s*[\""']*[\w,\\]*(.\w+)*[\""']*\s*),(\s*[\""']*[\w,\\]*(.\w+)*[\""']*)\s*\)";
string input = @"AreEqual  ( ""test"" ,  Obj.Prop ) && AreEqual ( 1 , 2 ) && AREeQuAl( Obj.Prop , 1 )&& AreEqual (""\""\"","" , 2 ) AND AreEqual (',' , ',' ) AreEqual ( ""A,B"" , Obj.Prop )";

RegexOptions options = RegexOptions.Multiline | RegexOptions.IgnoreCase;

List<string> expectedOutputParts = new List<string>();
foreach (Match m in Regex.Matches(input, pattern, options))
{
    string newstring = $"MyClass.{m.Groups["1"]}( new ({m.Groups["2"]} AS A) , new ({m.Groups["4"]} AS A) )";
    expectedOutputParts.Add(newstring);         

}   

Console.WriteLine(string.Join(" && ", expectedOutputParts));

Выход:

MyClass.AreEqual( new ( "test" AS A) , new ( Obj.Prop AS A) ) && MyClass.AreEqual( new ( 1 AS A) , new ( 2 AS A) ) && MyClass.AREeQuAl( new ( Obj.Prop AS A) , new ( 1 AS A) ) && MyClass.AreEqual( new (',' AS A) , new ( ',' AS A) ) && MyClass.AreEqual( new ( "A,B" AS A) , new ( Obj.Prop AS A) )

Отказ от ответственности:

Эта версия не содержит часть AreEqual (""\""\"","" , 2 ). Я до сих пор не понял это.

2
Mong Zhu 12 Апр 2019 в 09:17

Вот общее решение:

        var texte = "AreEqual  ( \"test\" ,  Obj.Prop ) && AreEqual ( 1 , 2 ) && AREeQuAl( Obj.Prop , 1 )&& AreEqual (\",\" , 2 ) AND AreEqual (',' , ',' ) AreEqual(\"A,B\", Obj.Prop)";

        //Extract function
        MatchCollection matches = Regex.Matches(texte, @".+?(?=\()");
        var function = Regex.Matches(texte, @".+?(?=\()")[0].ToString().Trim();


        var patternARGS = @"(?<=\().+? (?=\))";
        var patternExtractARGS = @"""[^, ]* , [^, ]*""( , )""[^, ]* , [^,]*""|[^, ]* , [^, ]*""( , )[^""]+""|[^""]+( , )""[^,]* , [^,]*""|( , )";

        // extract all arg between parenthesis
        matches = Regex.Matches(texte, patternARGS);

        //extract all args from previous result, with the difficulty to identify the right ','
        List<String> args = new List<String>();
        foreach (Match m in matches)
        {
            System.Diagnostics.Debug.WriteLine($"{m}");
            MatchCollection x = Regex.Matches(m.ToString(),patternExtractARGS);
            GroupCollection commas = x[0].Groups;

            var index = (commas.SyncRoot as Match).Index;
            var len = (commas.SyncRoot as Match).Length;
            var a1 = m.ToString().Substring(0, index);
            var a2 = m.ToString().Substring(index + len - 1);
            args.Add($"MyClass.{ function}( new ({a1}), new ({a2}))");
        }


        //extract conditions && AND...)
        var patternCONDITION = @"(?<=\)).+?(?=(?i: " + function + "))";
        matches = Regex.Matches(texte, patternCONDITION);



        var output = args[0];
        for(int i = 1;i<args.Count;i++)
        {
            output = output + $" {matches[i - 1].ToString().Trim()} {args[i]}";
        }

Результат в выходе.

0
Frenchy 12 Апр 2019 в 12:12