简体   繁体   中英

C# regex. Everything inside curly brackets{} and mod(%) charaters

I'm trying to get the values between {} and %% in a same Regex. This is what I have till now. I can successfully get values individually for each but I was curious to learn about how can I combine both.

var regex = new Regex(@"%(.*?)%|\{([^}]*)\}");

String s = "This is a {test} %String%. %Stack% {Overflow}";

Expected answer for the above string

test
String
Stack
Overflow

Individual regex

@"%(.*?)%" gives me String and Stack
@"\{([^}]*)\}" gives me test and Overflow

Following is my code.

var regex = new Regex(@"%(.*?)%|\{([^}]*)\}");
var matches = regex.Matches(s); 
foreach (Match match in matches) 
{
    Console.WriteLine(match.Groups[1].Value);
}

Similar to your regex. You can use Named Capturing Groups

String s = "This is a {test} %String%. %Stack% {Overflow}";
var list = Regex.Matches(s, @"\{(?<name>.+?)\}|%(?<name>.+?)%")
           .Cast<Match>()
           .Select(m => m.Groups["name"].Value)
           .ToList();

If you want to learn how conditional expressions work, here is a solution using that kind of .NET regex capability:

(?:(?<p>%)|(?<b>{))(?<v>.*?)(?(p)%|})

See the regex demo

Here is how it works:

  • (?:(?<p>%)|(?<b>{)) - match and capture either Group "p" with % (percentage), or Group "b" (brace) with {
  • (?<v>.*?) - match and capture into Group "v" (value) any character (even a newline since I will be using RegexOptions.Singleline ) zero or more times, but as few as possible (lazy matching with *? quantifier)
  • (?(p)%|}) - a conditional expression meaning: if "p" group was matched, match % , else, match } .

在此输入图像描述

C# demo :

var s = "This is a {test} %String%. %Stack% {Overflow}";
var regex = "(?:(?<p>%)|(?<b>{))(?<v>.*?)(?(p)%|})";
var matches = Regex.Matches(s, regex, RegexOptions.Singleline); 
// var matches_list = Regex.Matches(s, regex, RegexOptions.Singleline)
//                 .Cast<Match>() 
//                 .Select(p => p.Groups["v"].Value)
//                 .ToList(); 
// Or just a demo writeline
foreach (Match match in matches) 
    Console.WriteLine(match.Groups["v"].Value);

Sometimes the capture is in group 1 and sometimes it's in group 2 because you have two pairs of parentheses.

Your original code will work if you do this instead:

Console.WriteLine(match.Groups[1].Value + match.Groups[2].Value);

because one group will be the empty string and the other will be the value you're interested in.

@"[\{|%](.*?)[\}|%]"

The idea being:

{ or %
anything
} or %

我认为你应该使用条件和嵌套组的组合:

((\{(.*)\})|(%(.*)%))

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