Extract repeated patterns from a single-line string using Regex

Viewed 73

I have a string that looks like the following:

attr one = 1 attr two = 2

I would like to extract each attr x = y (where x and y can be anything including whitespace, not just numbers for example: attr name = Jonah).

I tried the following pattern: Regex pattern = new Regex(@"attr\s+(?<name>.*)\s+=\s+(?<value>.*)") but it returns the entire string in a single match and doesn't separate them.

How can I achieve that?

1 Answers

You may use

\battr\s+(?<name>\S*)\s+=\s+(?<value>.*?)(?=\s+attr\s|\z)

See the regex demo

Details

  • \battr - a whole word attr
  • \s+ - 1+ whitespaces
  • (?<name>\S*) - Group "name": 0 or more non-whitespace chars
  • \s+=\s+ - a = char enclosed with 1+ whitespaces
  • (?<value>.*?) - Group "value": any 0 or more chars other than a newline as few as possible...
  • (?=\s+attr\s|\z) - that is immediately followed with 1+ whitespaces, attr and a whitespace, or with the end of string.

See a C# demo (assuming the names are all unique):

var text = "attr one = one two three attr two = 3";
var dct = Regex.Matches(text, @"\battr\s+(?<name>\S*)\s+=\s+(?<value>.*?)(?=\s+attr\s|\z)")
        .Cast<Match>()
        .ToDictionary(p => p.Groups["name"].Value, p => p.Groups["value"].Value); 
foreach (var kvp in dct)
    Console.WriteLine("{0} -> {1}", kvp.Key, kvp.Value);

Output:

one -> one two three
two -> 3
Related