一个正则表达式中可以匹配多个组吗?

4

我正在尝试在.NET中的同一正则表达式对象中匹配两个组,以便可以分别处理它们;我不想为每个单独的表达式实例化许多对象。基本上,我想在句点前插入下划线,在感叹号前插入破折号。现在,我知道我可以使用标点符号构造,但我想将每个组用作单独的表达式。

这是我尝试过的无数方法的一个变体:

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");
            }
        }
    }

非常感谢您提前帮助。

1
我最喜欢的Replace(string,string, MatchEvaluator)函数可能会为您的情况提供更易读的代码...否则,请查看文档,并阅读有关替换模式,如$1的内容。 - Alexei Levenkov
3个回答

3

这应该可以工作。它使用了Lambda,但如果您想要更多的控制,可以将其拆分为函数。Match委托可以是任何一个。基本上,正则表达式引擎会调用您的委托来处理每个匹配项,并传入匹配的值,因此您可以根据需要即时决定如何处理它。

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

3
你可以使用 MatchEvaluator 将你的代码改写为以下形式:

不需要多个捕获组,你可以使用 字符类 来包含这两个字符。

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-!"

就多个组而言,.NET 不支持分支重置特性 (?| ... | ...),但你可以使用命名组来实现此功能,它们可以被无限制地重用。
string r = Regex.Replace(s, @"(?:(?<punc>\.)|(?<punc>!))", delegate(Match m) {
         return m.Groups["punc"].Value == "!" ? "-!" : "_.";
});

3

你的问题的答案是:你不能使用分组来做这个。多个替换字符串不被支持,也不能将替换字符串放入匹配本身中。

你可以使用正则表达式和匹配评估器来实现你想要的功能,就像其他答案所展示的那样,但是分组在其中没有任何作用。

你的问题的解决方案是:使用普通字符串替换。你没有做任何足够复杂的事情需要使用正则表达式。

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

哦,我明白了;我只是用标点符号的例子来看看是否可能对其他复杂组进行这样的操作。如果能完全避免使用正则表达式,那就太好了。 - Jesus Kevin Morales
如果您有复杂的正则表达式,即使string.Replace不足以满足需求,仍应使用两个单独的替换。 - Kendall Frey
+1。对于简单的替换选项来说很容易。顺便说一句:"不支持多个替换字符串"?我不太确定你的意思...你可以考虑用其他更清晰的方式表达你想要的意思。 - Alexei Levenkov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接