Ersetzen mit regex

Reguläre Ausdrücke werden gern verwendet, um flexibel Muster in Texten zu ersetzen. Natürlich bietet C++ auch die entsprechenden Schnittstellen.

Video

Quelltext

#include <iostream>
#include <regex>

using namespace std;

int main()
{
    string number { "1234,5678" };
    regex match { R"((\d+),(\d+))" };
    smatch sm;
    
    regex_match(number, sm, match);
    cout << sm.format("$1.$2") << endl;
    
    string s { "Ein Text, in dem ein paar *Wörter* rot *markiert werden* sollen." };
    regex r { R"(\*([^\*]+)\*)" };
    string bunt { "\x1b[31;1m$1\x1b[0m" };

    string result = regex_replace(s, r, bunt);

    cout << result << endl;
}

Erklärung

Grundlage für das Ersetzen von Matches in Texten ist die Methode format() des match_result-Objektes. Diese Methode nimmt einen Formatstring nach den Ersetzungsregeln von ECMAScript und formatiert den internen Zustand des match_result in einen String. Dabei können über die Ersetzungsvariablen $x (x steht für einen Integer) Teile des eigentlich match_result referenziert werden: eben jene Gruppen, die in der Regular Expression definiert werden können. Im Beispiel oben werden die erste und die zweite Gruppe (entsprechend $1 und $2) verwendet, um eine Kommazahl neu zusammenzusetzen (mit einem anderen Trenner).

match_result::format eignet sich allerdings nur zur Formatierung eines einzelnen Matches. Der wesentlich wichtigere Anwendungsfall ist meist, in einem Text Muster zu suchen und entsprechend zu ersetzen. Natürlich kann man das händisch über regex_search und dann ein entsprechendes Durchhangeln betreiben. Will man aber nicht, man ist ja faul. Ergo: regex_replace eilt zur Rettung. Dieser Algorithmus verpackt nämlich genau dieses Vorgehen in einen einfachen Funktionsaufruf. Die hier verwendete Variante nimmt den Ausgangsstring, den regulären Ausdruck und den Formatstring als Parameter und liefert einen String mit den entsprechenden Ersetzungen zurück. Hier im Beispiel werden Elemente, die in * eingefasst sind, durch ANSI-Escapecodes ersetzt, die die entsprechenden Textteile auf der Konsole rot einfärben.