简体   繁体   中英

An optional element in C# RegEx matching expression

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.

Qualify that the whole test2 group is optional:

@"test1=(?<test1>(\d+))((.|\s)+?)(test2=(?<test2>(\d+)))?"

From MSDN - Regular Expression Language - Quick Reference :

? - Matches the previous element zero or one time.

add a ? after the element you want to be optional

.|\\s can 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)

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