SDK Multiplataforma en C logo

SDK Multiplataforma en C

Expresiones regulares

❮ Anterior
Siguiente ❯

Funciones

RegEx*regex_create (...)
voidregex_destroy (...)
bool_tregex_match (...)

Las expresiones regulares definen un patrón de texto que puede utilizarse para buscar o comparar cadenas (Listado 1).

  • Utiliza regex_create para crear una expresión regular.
  • Utiliza regex_match para comprobar si una cadena cumple con el patrón.
  • Listado 1: Uso de expresiones regulares.
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    
    RegEx *regex = regex_create(".*.txt");
    
    const char_t *str[] = {
        "file01.txt",
        "image01.png",
        "sun01.jpg",
        "films.txt",
        "document.pdf"};
    
    uint32_t i, n = sizeof(str) / sizeof(char_t*);
    
    for (i = 0; i < n; ++i)
    {
        if (regex_match(regex, str[i]) == TRUE)
            bstd_printf("YES: %s\n", str[i]);
        else
            bstd_printf("NO:  %s\n", str[i]);
    }
    
    regex_destroy(®ex);
    
    Resultado de (Listado 1).
    1
    2
    3
    4
    5
    
    YES: file01.txt
    NO:  image01.png
    NO:  sun01.jpg
    YES: films.txt
    NO:  document.pdf
    

1. Definir patrones

Podemos construir una expresión regular a partir de una cadena de texto, siguiendo estas sencillas reglas:

  • Un patrón cadena se corresponde únicamente con esa misma cadena.
  •  
    
    "hello" --> {"hello"}
    
  • Un punto '.' equivale a "cualquier carácter".
  •  
    
    "h.llo" --> {"hello", "htllo", "hällo", "h5llo", ...}
    
  • Un guión 'A-Z' establece un rango de caracteres, utilizando el código Unicode de ambos extremos.
  •  
    
    "A-Zello" --> {"Aello", "Bello", "Cello", ..., "Zello"}
    
    'A-Z': (65-90) (ABCDEFGHIJKLMNOPQRSTUVWXYZ)
    '0-9': (48-57) (0123456789)
    'á-ú': (225-250) (áâãäåæçèéêëìíîïðñòóôõö÷øùú)
    
Al igual que los objetos String, los patrones se expresan en UTF-8, por tanto, puede utilizarse todo el conjunto Unicode para crear expresiones regulares.
  • Los corchetes '[áéíóú]' permiten alternar entre varios caracteres.
  •  
    
    "h[áéíóú]llo" --> {"hállo", "héllo", "híllo", "hóllo", "húllo"}
    
  • El asterisco '*' permite que el último carácter aparezca cero o más veces.
  •  
    
    "he*llo" --> {"hllo", "hello", "heello", "heeello", "heeeello", ...}
    "h.*llo" --> {"hllo", "hello", "hallo", "hillo", "hasello", ...}
    "hA-Z*llo" --> {"hllo", "hAllo", "hABllo", "hVFFRREASllo" }
               --> {"hAQWEDllo", hAAABBRSllo", ...}
    "FILE_0-9*.PNG" --> {"FILE_.PNG", "FILE_0.PNG", "FILE_01.PNG" }
                    --> {"FILE_456.PNG", "FILE_112230.PNG",...}
    
  • Los paréntesis '(he*llo)' permiten agrupar una expresión regular, de tal forma que se comporte como un único carácter.
  •  
    
    "[(hello)(bye)]" --> {"hello", "bye" }
    "[(red)(blue)(1*)]" --> {"red", "blue", "", "1", "11", "111", ... }
    "(hello)*" --> {"", "hello", "hellohello", "hellohellohello", ... }
    "(he*llo)ZZ" --> {"hlloZZ", "helloZZ", "heelloZZ", "heeelloZZ", ... }
    
  • Para que '.', '-', '[]', '*', '()' sean interpretados como carácteres, utilizar el backslash '\'.
  •  
    
    "\(he\*\-llo\)" --> {"(he*-llo)"}
    
Recuerda que para expresiones insertadas como constantes en código C, el carácter backslash se representa con doble barra "\\\\(he\\\\*\\\\-llo\\\\)".

2. Lenguajes regulares y autómatas

Los lenguajes regulares son aquellos que se definen de forma recursiva utilizando tres operaciones básicas sobre el conjunto de carácteres (o símbolos) disponibles. Se pueden describir mediante las expresiones regulares comentadas anteriormente.

  • Cada carácter 'a' es un lenguaje regular 'A'.
  • La unión de dos lenguajes regulares, es un lenguaje regular A∪B.
  • La concatenación de dos lenguajes regulares, es un lenguaje regular A·B.
  • La clausura de un lenguaje regular, es un lenguaje regular A*. Aquí es donde entra en juego la recursión.
En este contexto los símbolos son todos los carácteres Unicode. Pero pueden definirse lenguajes basados en otros alfabetos, incluído el binario {0, 1}.

Para reconocer si una cadena pertenece o no a un determinado lenguaje regular, es necesario construir un Autómata Finito basándonos en las reglas reflejadas en (Figura 1).

Concatenación, Unión y Clausura de autómatas finitos.
Figura 1: Construcción de autómatas finitos para filtrar expresiones regulares.

regex_create ()

Crea una expresión regular a partir de un patrón.

RegEx*
regex_create(const char_t *pattern);
pattern

Patrón de búsqueda.

Retorna

Expresión regular (autómata).

Observaciones

Ver Definir patrones.


regex_destroy ()

Destruye una expresión regular.

void
regex_destroy(RegEx **regex);
regex

Expresión regular. Será puesto a NULL tras la destrucción.


regex_match ()

Comprueba si una cadena cumple el patrón de búsqueda.

bool_t
regex_match(const RegEx *regex,
            const char_t *str);
regex

Expresión regular.

str

Cadena a evaluar.

Retorna

TRUE si la cadena es aceptada por la expresión regular.

❮ Anterior
Siguiente ❯