Jesus Kevin Morales
Jesus Kevin Morales

Reputation: 123

Multiple groups in one regex?

I'm trying to match two groups in the same Regex object in .NET, so I can process them separately; I'd hate to instantiate many objects for every individual expression. Basically, I'd like to insert an underscore before a period and a dash before an exclamation point. Now, I know I can use punctuation constructs, but I'd like to use each group as an individual expression.

Here's a variation of the million ways I've tried:

using System.Text.RegularExpressions;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
    {
    public partial class Form1 : Form
        {
        public Form1()
            {
            InitializeComponent();
            var rule = new Regex(@"(\.)(\!)", RegexOptions.Compiled);
            var myText = "string. will! way. water! test. quiz! short. long!";
            richTextBox1.Text = rule.Replace(rule.Replace(myText, "_$1"), "-$2");
            }
        }
    }

Thanks so much in advance.

Upvotes: 4

Views: 196

Answers (3)

hwnd
hwnd

Reputation: 70732

You can use MatchEvaluator rewriting your code as follows:

Instead of multiple capturing groups you can use a Character Class to include both characters.

string s = "string. will! way. water! test. quiz! short. long!";
string r = Regex.Replace(s, @"[!.]", delegate(Match m) {
         return m.Value == "!" ? "-!" : "_.";
});

//=> "string_. will-! way_. water-! test_. quiz-! short_. long-!"

As far as multiple groups .NET doesn't support the branch reset feature (?| ... | ... ), but one way you could do this would be named groups, you can reuse them without restriction.

string r = Regex.Replace(s, @"(?:(?<punc>\.)|(?<punc>!))", delegate(Match m) {
         return m.Groups["punc"].Value == "!" ? "-!" : "_.";
});

Upvotes: 3

Kendall Frey
Kendall Frey

Reputation: 44326

The answer to your question is: You can't use groups to do that. Multiple replacement strings just aren't supported, and neither is putting the replacement string into the match itself.

You can use a regex and a match evaluator to do what you want, as the other answers show, but groups play no part in that.

The solution to your problem is: Use plain string replacements. You're not doing anything complicated enough to require a regex.

var myText = "string. will! way. water! test. quiz! short. long!";
richTextBox1.Text = myText.Replace(".", "_.").Replace("!", "-!");

Upvotes: 3

mrjoltcola
mrjoltcola

Reputation: 20842

This should work. It uses a Lamba, but if you want more control you can break it out into a function. The Match delegate can be either. Basically the regex engine calls your delegate with each match, passing in the matched value, so you can decide what to do with it on the fly.

Regex.Replace("Test a. b!", @"([.!])",
       (m) => { return m.Value == "." ? "_." : "-!"; }
    );

Upvotes: 3

Related Questions