HOWTO · C
Expresiones Regulares en C
En este artículo, hablaremos sobre las expresiones regulares en C.
En esta página
Las funciones de expresiones regulares de POSIX permiten que un programa en C compile un patrón, pruebe cadenas y compruebe si cada prueba encontró una coincidencia. Las expresiones regulares no forman parte del lenguaje C; este artículo utiliza la interfaz POSIX <regex.h>.
Expresiones regulares en C con POSIX
Una expresión regular describe un patrón de texto. POSIX ofrece dos sintaxis principales para los patrones: las expresiones regulares básicas y las extendidas. En los ejemplos siguientes se selecciona la sintaxis extendida con REG_EXTENDED.
Las expresiones entre corchetes permiten encontrar un carácter de un conjunto. Por ejemplo, [abc] coincide con a, b o c; [[:digit:]] coincide con un dígito; [[:alnum:]_] coincide con un carácter alfanumérico o un guion bajo; y [[:lower:]] coincide con una letra minúscula según la configuración regional activa. Una clase de caracteres POSIX debe escribirse dentro de una expresión entre corchetes, por lo que formas como [:number:] y [:word:] no son clases estándar. Use [[:digit:]] para los dígitos y [[:alnum:]_] si necesita letras, dígitos y guion bajo.
El comportamiento de las coincidencias puede depender de la configuración regional actual, especialmente en las clases de caracteres y al ignorar mayúsculas y minúsculas. Configure la región de forma deliberada si la aplicación necesita reglas específicas. Las implementaciones de POSIX proporcionan esta API, pero el lenguaje C por sí solo no la garantiza.
Compilar una expresión regular POSIX con regcomp()
Declare un objeto regex_t para almacenar la expresión compilada y pase a regcomp() su dirección, un patrón terminado en NUL y las opciones de compilación. Con REG_EXTENDED, operadores como + usan la sintaxis de expresiones regulares extendidas. Añada REG_ICASE para que las coincidencias no distingan entre mayúsculas y minúsculas, o REG_NOSUB si no necesita las posiciones de las subcoincidencias.
regcomp() devuelve 0 cuando la compilación se realiza correctamente. Un valor distinto de cero es un código de error; no es un valor de errno. Use regerror() con el mismo objeto regex_t para generar un mensaje de diagnóstico. Llame a regfree() únicamente después de una compilación correcta.
Comparar cadenas con regexec() y liberar la expresión regular compilada
Llame a regexec() con el objeto regex_t compilado y una cadena terminada en NUL. El valor de retorno 0 indica que hay una coincidencia, mientras que REG_NOMATCH indica que el patrón no coincidió. Cualquier otro valor señala un error de ejecución y se puede convertir en un mensaje con regerror(). Si necesita las posiciones de las subcoincidencias, proporcione una matriz de elementos regmatch_t y su capacidad; la primera entrada describe la coincidencia completa. Con REG_NOSUB, no solicite posiciones de subcoincidencias.
Este ejemplo completo compila un patrón, prueba dos cadenas y libera el objeto compilado. Informa de los errores de compilación y ejecución mediante regerror(). En la ejecución correcta suministrada, imprimió match y luego no match, y terminó con el código 0. Las etiquetas match y no match que muestra el ejemplo permanecen en inglés.
Ejecute este ejemplo:
#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
El ejemplo comprueba cada valor de retorno antes de usarlo y conserva la expresión compilada hasta haber probado ambas cadenas. La ejecución suministrada terminó con el código 0. El ejemplo requiere una implementación POSIX de <regex.h>.