HOWTO · C
Reguläre Ausdrücke in C
In diesem Artikel sprechen wir über reguläre Ausdrücke in C.
Auf dieser Seite
Mit POSIX-Funktionen für reguläre Ausdrücke kann ein C-Programm ein Muster kompilieren, Zeichenketten damit abgleichen und feststellen, ob ein Abgleich erfolgreich war. Reguläre Ausdrücke gehören nicht zur C-Sprache selbst; dieser Artikel verwendet die POSIX-Schnittstelle <regex.h>.
Reguläre Ausdrücke in C mit POSIX
Ein regulärer Ausdruck beschreibt ein Muster in Text. POSIX stellt zwei grundlegende Mustersyntaxen bereit: einfache und erweiterte reguläre Ausdrücke. Die folgenden Beispiele wählen mit REG_EXTENDED die erweiterte Syntax.
Klammerausdrücke finden ein Zeichen aus einer Menge. Zum Beispiel findet [abc] a, b oder c; [[:digit:]] findet eine Ziffer; [[:alnum:]_] findet ein alphanumerisches Zeichen oder einen Unterstrich; und [[:lower:]] findet im aktiven Gebietsschema einen Kleinbuchstaben. Eine POSIX-Zeichenklasse muss innerhalb eines Klammerausdrucks stehen. Formen wie [:number:] und [:word:] sind daher keine standardisierten Klassen. Verwenden Sie [[:digit:]] für Ziffern und [[:alnum:]_], wenn Sie Buchstaben, Ziffern und Unterstriche abgleichen möchten.
Das Abgleichverhalten kann vom aktuellen Gebietsschema abhängen, insbesondere bei Zeichenklassen und der Groß- und Kleinschreibung. Legen Sie das Gebietsschema bewusst fest, wenn eine Anwendung gebietsschemaspezifische Regeln benötigt. Diese API wird von POSIX-Implementierungen bereitgestellt, ist aber nicht allein durch die C-Sprache garantiert.
Einen POSIX-regulären Ausdruck mit regcomp() kompilieren
Deklarieren Sie ein Objekt vom Typ regex_t, das den kompilierten Ausdruck aufnimmt. Übergeben Sie dann seine Adresse, ein mit NUL abgeschlossenes Muster und die Kompilierungsflags an regcomp(). Mit REG_EXTENDED werden Operatoren wie + gemäß der erweiterten Syntax für reguläre Ausdrücke interpretiert. Ergänzen Sie REG_ICASE für einen Abgleich ohne Beachtung der Groß- und Kleinschreibung oder REG_NOSUB, wenn Sie keine Offsets von Teiltreffern benötigen.
Bei erfolgreicher Kompilierung gibt regcomp() 0 zurück. Ein Rückgabewert ungleich null ist ein Fehlercode und kein errno-Wert. Verwenden Sie regerror() mit demselben regex_t-Objekt, um eine Diagnose zu formatieren. Rufen Sie regfree() nur nach erfolgreicher Kompilierung auf.
Zeichenketten mit regexec() abgleichen und den kompilierten regulären Ausdruck freigeben
Rufen Sie regexec() mit dem kompilierten regex_t-Objekt und einer mit NUL abgeschlossenen Zeichenkette auf. Der Rückgabewert 0 bedeutet, dass ein Treffer gefunden wurde; REG_NOMATCH bedeutet, dass das Muster nicht auf die Zeichenkette passt. Jeder andere Wert zeigt einen Ausführungsfehler an, der sich mit regerror() formatieren lässt. Wenn Sie die Positionen von Teiltreffern benötigen, übergeben Sie ein Array aus regmatch_t-Einträgen samt seiner Kapazität; der erste Eintrag beschreibt den Gesamttreffer. Mit REG_NOSUB dürfen Sie keine Positionen von Teiltreffern anfordern.
Das vollständige Beispiel kompiliert ein Muster, prüft zwei Zeichenketten und gibt das kompilierte Objekt anschließend frei. Bei Kompilierungs- und Ausführungsfehlern gibt es Diagnosen über regerror() aus. Im bereitgestellten erfolgreichen Lauf gab es zuerst match und danach no match aus; der Exitcode war 0.
Führen Sie dieses Beispiel aus:
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
#include <regex.h>
#include <stddef.h>
#include <stdio.h>
int main(void) {
regex_t re;
const char *pattern = "[[:alpha:]]+";
int status = regcomp(&re, pattern, REG_EXTENDED);
if (status != 0) {
char message[256];
regerror(status, &re, message, sizeof message);
printf("compile: %s\n", message);
return 1;
}
const char *samples[] = {"C language", "123"};
for (size_t i = 0; i < sizeof samples / sizeof samples[0]; ++i) {
status = regexec(&re, samples[i], 0, NULL, 0);
if (status == 0) {
puts("match");
} else if (status == REG_NOMATCH) {
puts("no match");
} else {
char message[256];
regerror(status, &re, message, sizeof message);
printf("execution: %s\n", message);
}
}
regfree(&re);
return 0;
}
match
no match
Das Beispiel prüft jeden Rückgabewert, bevor es ihn weiterverwendet, und behält den kompilierten Ausdruck, bis beide Zeichenketten geprüft wurden. Der bereitgestellte Lauf endete mit Exitcode 0. Die unveränderten Ausgabebezeichnungen match und no match sind englisch. Für das Beispiel ist eine POSIX-Implementierung von <regex.h> erforderlich.