2012-06-20 21 views
5

Parece que no puedo hacer que mi expresión regular funcione correctamente. En un texto de varias líneas en ECMAScript esta expresión regular begin\n([\s\S]*\nend)? coincide exactamente con lo que necesito, y I tested it here.C++ std :: regex multiline sintaxis

Cuando lo traduzco en C++, no coincide con el mismo texto.

Aquí está mi código en Visual C++ 2010:

#include <iostream> 
#include <regex> 

int main(int argc, char *argv[]) { 
    std::regex metadataBlockRegex("begin\\n([\\s\\S]*\\nend)?", 
     std::regex::ECMAScript); 

    std::string text = 
     "begin\n" 
     " 123\n" 
     "end\n"; 

    std::sregex_iterator blocksBegin(text.begin(), text.end(), metadataBlockRegex); 
    std::sregex_iterator blocksEnd; 

    for (auto blockMatch = blocksBegin; blockMatch != blocksEnd; ++blockMatch) { 
      std::cout << (*blockMatch)[0].str(); 
    } 
    return 0; 
} 

Esto sólo produce la salida "begin" y que esperaba que coincide con el texto completo.

Mi pregunta es: ¿qué hay de malo aquí y dónde puedo encontrar una descripción detallada de la sintaxis de los motores std::regex y cómo manejan cadenas multilínea.

+0

Este programa imprime todo el texto (excepto el último '\ n', que no coincide) con clang ++/libC++ – Cubbi

+0

Esto se comporta como describe Gart en MSVC10. La nueva línea no coincide, y nada está detrás de ella. –

+0

También imprime la cadena completa con 'boost :: regex' –

Respuesta

-1

LWG 2503 agregaron la opción de sintaxis multiline, que debería hacer que su programa funcione como se esperaba cuando utiliza la opción (para implementaciones C++ que admiten esa nueva característica).

LWG 2343 tiene más antecedentes, lo que explica que los objetos ECMAScript RegExp tienen una propiedad Multiline, que por defecto es falsa, y el comportamiento de diferentes implementaciones de C++ regex.

Respuesta original a partir de 2012:

lo que está mal aquí

No estoy seguro, se ve bien, pero las únicas C++ 11 implementaciones que tienen acceso a no apoyar <regex>

donde puedo encontrar una descripción detallada de la sintaxis de los motores std :: regex y cómo manejan cadenas multilínea.

No puede, hasta donde yo sé. El mejor lugar para buscar es probablemente la documentación para Boost.Regex, pero tenga en cuenta que se ha movido desde que se propuso para la estandarización y tiene algunas características que no están presentes en std::regex.

+0

Eso es muy triste – Gart

+0

Josuttis tiene una descripción de cómo difieren las diferentes gramáticas de expresiones regulares. El comportamiento que está viendo sería consistente con la gramática egrep, donde \ n separa patrones alternativos, por lo que 'begin' es una coincidencia válida para el primer patrón. La gramática ECMAScript no debería tratar \ n así como así. –

5

Sin soporte multilínea, de todos modos ... no en MSVC10.

Necesitas multilínea falso con \ r & \ n en sus patrones. Es un fastidio importante.