如何从字符串中解析特定的函数名及其参数?
How to parse a specific function name and its parameters from string?
我正在尝试解析函数名称及其参数以更新字符串内容。我将函数调用存储在一个字符串中,在调用它之前我需要修改它然后调用。以下是包含函数的字符串。
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();
}
}
我尝试将项目匹配到组中,然后使用这些组格式化新字符串。
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 )
部分。我还没弄明白。
这是一个通用的解决方案:
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]}";
}
输出结果。
我正在尝试解析函数名称及其参数以更新字符串内容。我将函数调用存储在一个字符串中,在调用它之前我需要修改它然后调用。以下是包含函数的字符串。
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();
}
}
我尝试将项目匹配到组中,然后使用这些组格式化新字符串。
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 )
部分。我还没弄明白。
这是一个通用的解决方案:
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]}";
}
输出结果。