242 Stimmen

Ersetzen Sie nur einige Gruppen mit Regex

Nehmen wir an, ich habe die folgende Regex:

-(\d+)-

und ich möchte mit C# die Gruppe 1 ersetzen (\d+) con AA zu erhalten:

-AA-

Jetzt ersetze ich es durch:

var text = "example-123-example";
var pattern = @"-(\d+)-";
var replaced = Regex.Replace(text, pattern, "-AA-"); 

Aber ich mag das nicht wirklich, denn wenn ich das Muster so ändere, dass es mit _(\d+)_ muss ich stattdessen die Ersetzungszeichenfolge durch _AA_ und das widerspricht dem DRY-Prinzip.

Ich bin auf der Suche nach etwas wie:

Behalten Sie den übereinstimmenden Text unverändert bei, ändern Sie aber die Gruppe 1 um this text und Gruppe 2 durch another text ...

編集する:
Das war nur ein Beispiel. Ich bin gerade auf der Suche nach einer allgemeinen Möglichkeit, das zu tun, was ich oben gesagt habe.

Es sollte funktionieren für:

anything(\d+)more_text und jedes andere Muster, das Sie sich vorstellen können.

Ich möchte nur die Gruppen ersetzen und den Rest des Spiels beibehalten.

405voto

bluepnume Punkte 15314

Eine gute Idee könnte sein, alles in Gruppen zu kapseln, unabhängig davon, ob sie identifiziert werden müssen oder nicht. Auf diese Weise können Sie sie in Ihrer Ersetzungszeichenfolge verwenden. Zum Beispiel:

var pattern = @"(-)(\d+)(-)";
var replaced = Regex.Replace(text, pattern, "$1AA$3"); 

oder einen MatchEvaluator verwenden:

var replaced = Regex.Replace(text, pattern, m => m.Groups[1].Value + "AA" + m.Groups[3].Value);

Eine andere, etwas chaotische Möglichkeit wäre die Verwendung eines Nach- oder Vorausblicks:

(?<=-)(\d+)(?=-)

42voto

LukeH Punkte 251752

Sie können dies tun mit Vorausschau und Rückschau :

var pattern = @"(?<=-)\d+(?=-)";
var replaced = Regex.Replace(text, pattern, "AA");

25voto

Daniel Hilgarth Punkte 165768

Ich hatte auch Bedarf daran und habe die folgende Erweiterungsmethode dafür erstellt:

public static class RegexExtensions
{
    public static string ReplaceGroup(
        this Regex regex, string input, string groupName, string replacement)
    {
        return regex.Replace(
            input,
            m =>
            {
                var group = m.Groups[groupName];
                var sb = new StringBuilder();
                var previousCaptureEnd = 0;
                foreach (var capture in group.Captures.Cast<Capture>())
                {
                    var currentCaptureEnd =
                        capture.Index + capture.Length - m.Index;
                    var currentCaptureLength =
                        capture.Index - m.Index - previousCaptureEnd;
                    sb.Append(
                        m.Value.Substring(
                            previousCaptureEnd, currentCaptureLength));
                    sb.Append(replacement);
                    previousCaptureEnd = currentCaptureEnd;
                }
                sb.Append(m.Value.Substring(previousCaptureEnd));

                return sb.ToString();
            });
    }
}

Verwendung:

var input = @"[assembly: AssemblyFileVersion(""2.0.3.0"")][assembly: AssemblyFileVersion(""2.0.3.0"")]";
var regex = new Regex(@"AssemblyFileVersion\(""(?<version>(\d+\.?){4})""\)");

var result = regex.ReplaceGroup(input , "version", "1.2.3");

Ergebnis:

[assembly: AssemblyFileVersion("1.2.3")][assembly: AssemblyFileVersion("1.2.3")]

14voto

Dick Verweij Punkte 149

Wenn Sie Ihr Muster nicht ändern möchten, können Sie die Eigenschaften Gruppenindex und Länge einer übereinstimmenden Gruppe verwenden.

var text = "example-123-example";
var pattern = @"-(\d+)-";
var regex = new RegEx(pattern);
var match = regex.Match(text);

var firstPart = text.Substring(0,match.Groups[1].Index);    
var secondPart = text.Substring(match.Groups[1].Index + match.Groups[1].Length);
var fullReplace = firstPart + "AA" + secondPart;

6voto

curlyhairedgenius Punkte 794

Hier ist eine weitere saubere Option, bei der das Muster nicht geändert werden muss.

        var text = "example-123-example";
        var pattern = @"-(\d+)-";

        var replaced = Regex.Replace(text, pattern, (_match) =>
        {
            Group group = _match.Groups[1];
            string replace = "AA";
            return String.Format("{0}{1}{2}", _match.Value.Substring(0, group.Index - _match.Index), replace, _match.Value.Substring(group.Index - _match.Index + group.Length));
        });

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X