jondow
jondow

Reputation: 724

How do I match a regex pattern and extract data from it

I can have 0 or many substrings within a text area in the format {key-value}Some text{/key},

For example This is my {link-123}test{/link} text area

I'd like to iterate through any items that match this pattern, perform and action based on the key and value, then replace this substring with a new string (a anchor link that is retreived by the action based on the key).

How would I achieve this in C#?

Upvotes: 3

Views: 2156

Answers (3)

Grimace of Despair
Grimace of Despair

Reputation: 3506

Something like this?

Regex.Replace(text,

  "[{](?<key>[^-]+)-(?<value>[^}])[}](?<content>.*?)[{][/]\k<key>[}]",
  match => {

    var key = match.Groups["key"].Value;
    var value= match.Groups["value"].Value;
    var content = match.Groups["content"].Value;

  return string.format("The content of {0}-{1} is {2}", key, value, content);
});

Upvotes: 1

Tim Pietzcker
Tim Pietzcker

Reputation: 336178

If these tags are not nested, then you only need to iterate once over the file; if nesting is possible, then you need to do one iteration for each level of nesting.

This answer assumes that braces only occur as tag delimiters (and not, for example, inside comments):

result = Regex.Replace(subject, 
    @"\{                # opening brace
    (?<key>\w+)         # Match the key (alnum), capture into the group 'key'
    -                   # dash
    (?<value>\w+)       # Match the value (alnum), capture it as above
    \}                  # closing brace
    (?<content>         # Match and capture into the group 'content':
     (?:                # Match...
      (?!\{/?\k<key>)   # (unless there's an opening or closing tag
      .                 # of the same name right here) any character
     )*                 # any number of times
    )                   # End of capturing group
    \{/\k<key>\}        # Match the closing tag.", 
    new MatchEvaluator(ComputeReplacement), RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace);

public String ComputeReplacement(Match m) {
    // You can vary the replacement text for each match on-the-fly
    // m.Groups["key"].Value will contain the key
    // m.Groups["value"].Value will contain the value of the match
    // m.Groups["value"].Value will contain the content between the tags
    return ""; // change this to return the string you generated here
}

Upvotes: 3

Phillip Scott Givens
Phillip Scott Givens

Reputation: 5464

Use the .net Regular Expression libraries. Here is an example that uses the Matches method:

http://www.dotnetperls.com/regex-matches

For replacing text, consider using a templating engine such as Antlr

http://www.antlr.org/wiki/display/ANTLR3/Antlr+3+CSharp+Target

Here is the example from the Matches Blog

using System; using System.Text.RegularExpressions;

class Program
{
static void Main()
{
// Input string.
const string value = @"said shed see spear spread super";

// Get a collection of matches.
MatchCollection matches = Regex.Matches(value, @"s\w+d");

// Use foreach loop.
foreach (Match match in matches)
{
    foreach (Capture capture in match.Captures)
    {
    Console.WriteLine("Index={0}, Value={1}", capture.Index, capture.Value);
    }
}
}
}

For more information on the C# regular expression syntax, you could use this cheat sheet:

http://www.mikesdotnetting.com/Article/46/CSharp-Regular-Expressions-Cheat-Sheet

Upvotes: 0

Related Questions