HOWTO · C
Expressions régulières en C
Dans cet article, nous parlerons des expressions régulières en C.
Sur cette page
Les fonctions d’expressions régulières POSIX permettent à un programme C de compiler un motif, de tester des chaînes et de vérifier si chaque test a trouvé une correspondance. Les expressions régulières ne font pas partie du langage C lui-même ; cet article utilise l’interface POSIX <regex.h>.
Expressions régulières en C avec POSIX
Une expression régulière décrit un motif dans un texte. POSIX définit deux syntaxes principales pour les motifs : les expressions régulières de base et les expressions régulières étendues. Les exemples ci-dessous choisissent la syntaxe étendue avec REG_EXTENDED.
Les expressions entre crochets permettent de faire correspondre un caractère appartenant à un ensemble. Par exemple, [abc] correspond à a, b ou c ; [[:digit:]] correspond à un chiffre ; [[:alnum:]_] correspond à un caractère alphanumérique ou à un trait de soulignement ; et [[:lower:]] correspond à une lettre minuscule selon la locale active. Une classe de caractères POSIX doit figurer à l’intérieur d’une expression entre crochets : des formes comme [:number:] et [:word:] ne sont donc pas des classes standard. Utilisez [[:digit:]] pour les chiffres et [[:alnum:]_] pour les lettres, les chiffres et le trait de soulignement.
Le comportement de la recherche peut dépendre de la locale active, notamment pour les classes de caractères et la comparaison sans distinction de casse. Définissez la locale explicitement si votre application a besoin de règles propres à une locale. Cette API est fournie par les implémentations POSIX, mais le langage C seul ne la garantit pas.
Compiler une expression régulière POSIX avec regcomp()
Déclarez un objet regex_t pour stocker l’expression compilée, puis transmettez son adresse, un motif terminé par un caractère NUL et les indicateurs de compilation à regcomp(). Avec REG_EXTENDED, les opérateurs comme + suivent la syntaxe des expressions régulières étendues. Ajoutez REG_ICASE pour ignorer la casse ou REG_NOSUB si vous n’avez pas besoin des positions des sous-correspondances.
regcomp() renvoie 0 lorsque la compilation réussit. Toute valeur non nulle est un code d’erreur, et non une valeur errno. Utilisez regerror() avec le même objet regex_t pour formater un message de diagnostic. N’appelez regfree() qu’après une compilation réussie.
Tester des chaînes avec regexec() et libérer l’expression compilée
Appelez regexec() avec l’objet regex_t compilé et une chaîne terminée par un caractère NUL. La valeur de retour 0 indique une correspondance, tandis que REG_NOMATCH signifie que le motif ne correspond pas. Toute autre valeur indique une erreur d’exécution que vous pouvez formater avec regerror(). Pour obtenir les positions des sous-correspondances, fournissez un tableau d’entrées regmatch_t et sa capacité ; la première entrée décrit la correspondance complète. Avec REG_NOSUB, ne demandez pas les positions des sous-correspondances.
Cet exemple complet compile un motif, teste deux chaînes et libère l’objet compilé. Il signale les erreurs de compilation et d’exécution au moyen de regerror(). Lors de l’exécution réussie fournie, il a affiché match, puis no match, et s’est terminé avec le code 0. Ces deux libellés de sortie sont conservés en anglais dans l’exemple.
Exécutez cet exemple :
Le code et les libellés ou sorties affichés dans cette section restent en anglais.
#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
L’exemple vérifie chaque valeur de retour avant de l’utiliser et conserve l’expression compilée jusqu’à ce que les deux chaînes aient été testées. L’exécution fournie s’est terminée avec le code 0. L’exemple nécessite une implémentation POSIX de <regex.h>.