es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Coincidencia global utilizando PCRE

Intento hacer coincidir pares de clave-valor separados por comas utilizando PCRE. El texto se ve así:

"key1": "value1", "key2": "value2"

y el patrón probado es:

/(\s*)(,?)"([a-zA-Z0-9]+?)":(\s*)"([a-zA-Z0-9]+?)"/gm

Se puede probar el regex aquí:

Funciona en esta página de prueba, pero con este código C muestra solo el primer grupo coincidente.

pcre *re;
pcre_extra *sd;
const char *error;
int rc, erroroffset, i;
int ovector[OVECCOUNT];
re = pcre_compile(pattern, 0, &error, &erroroffset, NULL);
sd = pcre_study(
    re,             /* resultado de pcre_compile() */
    0,              /* sin opciones */
    &error);        /* establecer en NULL o apunta a un mensaje */
rc = pcre_exec(   /* ver más abajo los detalles de las opciones de pcre_exec() */
    re, sd, json, 7, 0, 0, ovector, 30);
pcre_free_study(sd);
printf("Coincidencia lograda en la posición %d\n", ovector[0]);
for (i = 0; i < rc; i++) {
    char *substring_start = json + ovector[2*i];
    int substring_length = ovector[2*i+1] - ovector[2*i];
    printf("%2d: '%.*s'\n", i, substring_length, substring_start);
}

El resultado es:

Coincidencia lograda en la posición 1
 0: '"key1": "value1"'
 1: ''
 2: ''
 3: 'key1'
 4: ' '
 5: 'value1'

pero necesito tener todos los grupos coincidentes, con:

'key2'
'value2'
Tags:  , ,

Answer

  1. Avatar for davy.ai

    El problema con el código C es que solo imprime el primer grupo coincidente. Para imprimir todos los grupos coincidentes, es necesario recorrerlos en un bucle.

    Aquí tienes una versión actualizada del código C que imprime todos los grupos coincidentes:

    pcre *re;
    pcre_extra *sd;
    const char *error;
    int rc, erroroffset, i, j;
    int ovector[OVECCOUNT];
    re = pcre_compile(patron, 0, &error, &erroroffset, NULL);
    sd = pcre_study(
        re,
        0,
        &error);
    rc = pcre_exec(
        re, sd, json, strlen(json), 0, 0, ovector, OVECCOUNT);
    pcre_free_study(sd);
    if (rc < 0) {
        printf("La coincidencia ha fallado\n");
    } else {
        printf("La coincidencia se ha realizado con éxito en la posición %d\n", ovector[0]);
        for (i = 0; i < rc; i++) {
            for (j = 0; j < 6; j += 2) {
                char *substring_start = json + ovector[i*6+j];
                int substring_length = ovector[i*6+j+1] - ovector[i*6+j];
                printf("%d: '%.*s'\n", j/2, substring_length, substring_start);
            }
        }
    }
    

    La principal diferencia es el bucle anidado que recorre los 6 grupos de captura e imprime sus subcadenas. Ten en cuenta que la variable del bucle j comienza en 0 y llega hasta 5, ya que hay 6 grupos de captura en la expresión regular.

    También ten en cuenta que añadí una comprobación para rc < 0, lo cual indica una falla en la coincidencia. En ese caso, el código imprimirá un mensaje de error en su lugar.

    Con estos cambios, el código actualizado debería imprimir tanto los pares clave-valor.

Comments are closed.