How to make 'test2' an optional element in the following C# RegEx expression getting 'test1' value parsed out correctly when 'test2' element is missing?
StringBuilder sb = new StringBuilder(); sb.AppendLine(" test1=123 any text in between "); sb.AppendLine(" some "); sb.AppendLine(" more "); sb.AppendLine(" text in between "); sb.AppendLine(" test2=456 "); sb.AppendLine(" test1=789 some text .. test2=012 "); Regex regex = new Regex(@"test1=(?<test1>(\d+))((.|\s)+?)(test2=(?<test2>(\d+)))"); MatchCollection matches = regex.Matches(sb.ToString()); foreach (Match match in matches) { Group test1 = match.Groups["test1"]; Group test2 = match.Groups["test2"]; System.Console.WriteLine("Test1 = {0}, Test2 = {1}", test1.Value, test2.Value); } Thank you.
@Oded - I reply here as I can't get comment formatted properly and as my reply is longer than allowed by StackOverflow comment text length:
Thank you. Proposed in your second reply RegEx expression results in the following output:
Test1 = 123, Test2 = Test1 = 789, Test2 = It's not quite correct. And your first reply RegEx expression results in
Test1 = 123, Test2 = 456 Test1 = 789, Test2 = 012 test output. That's is correct.
But if I change
sb.AppendLine(" test1=789 some text .. test2=012 "); to
sb.AppendLine(" test1=789 some text .. test52=012 "); then the test result output will have just one line
Test1 = 123, Test2 = 456 and I wanted it to be
Test1 = 123, Test2 = 456 Test1 = 789, Test2 = in that case.
02 Answers
Qualify that the whole test2 group is optional:
@"test1=(?<test1>(\d+))((.|\s)+?)(test2=(?<test2>(\d+)))?" From MSDN - Regular Expression Language - Quick Reference:
6? - Matches the previous element zero or one time.
add a ? after the element you want to be optional
.|\scan be replaced by . since . matches whitespace as well
To match newlines as well you have to pass Singleline option Regex regex = new Regex(@"test1=(?<test1>(\d+))((.)+?)(test2=(?<test2>(\d+)))?",RegexOptions.Singleline);
(The solution by Oded is does all this)
8