2009-08-10 11 views
23

Solo estoy entendiendo las expresiones regulares, y estoy usando la biblioteca Boost Regex.Cómo escapar de una cadena para usar en Boost Regex

Tengo la necesidad de usar una expresión regular que incluye una URL específica, y se bloquea porque, obviamente, hay caracteres en la URL que están reservados para expresiones regulares y deben escaparse.

¿Hay alguna función o método en la biblioteca de Boost para escapar de una cadena para este tipo de uso? Sé que hay tales métodos en la mayoría de las otras implementaciones de expresiones regulares, pero no veo uno en Boost.

Como alternativa, ¿hay una lista de todos los caracteres que deberían escaparse?

Respuesta

32
.^$ | () [ ] { } * + ? \ 

Irónicamente, podría utilizar una expresión regular para escapar de su URL para que pueda insertarse en una expresión regular.

const boost::regex esc("[.^$|()\\[\\]{}*+?\\\\]"); 
const std::string rep("\\\\&"); 
std::string result = regex_replace(url_to_escape, esc, rep, 
            boost::match_default | boost::format_sed); 

(La bandera boost::format_sed especifica para utilizar el formato de cadena de reemplazo de sed. En sed, una salida escapará & lo que sea igualada por toda la expresión)

O si no se siente cómodo con la cadena de reemplazo de sed formato, simplemente cambie el indicador a boost::format_perl, y puede usar el familiar $& para referirse a lo que corresponda con la expresión completa.

const std::string rep("\\\\$&"); 
std::string result = regex_replace(url_to_escape, esc, rep, 
            boost::match_default | boost::format_perl); 
+0

Intenté usar una expresión regular para hacerlo, pero todavía soy bastante incompetente, y ocurrieron cosas extrañas: p He ordenado un par de libros sobre expresiones regulares hoy, así que espero que mi ignorancia sea efímera. Mientras tanto, usar un reemplazo de cuerda regular para escapar de estos personajes funcionó para mis necesidades inmediatas, gracias. – Gerald

+0

Agregué un código a mi respuesta que * creo * debería funcionar para agregar una barra invertida antes de cualquier carácter que deba escaparse. No he usado boost en un tiempo, así que no hay garantías. – Amber

+7

Estaba cerca, solo tenía que agregar un "&" al final de la repetición y funcionó. Gracias. – Gerald

4

mismo con boost::xpressive:

const boost::xpressive::sregex re_escape_text = boost::xpressive::sregex::compile("([\\^\\.\\$\\|\\(\\)\\[\\]\\*\\+\\?\\/\\\\])"); 

std::string regex_escape(std::string text){ 
    text = boost::xpressive::regex_replace(text, re_escape_text, std::string("\\$1")); 
    return text; 
} 
11

Mediante el código de Dav (+ una solución de comentarios), creé función ASCII/Unicode regex_escape():

std::wstring regex_escape(const std::wstring& string_to_escape) { 
    static const boost::wregex re_boostRegexEscape(_T("[.^$|()\\[\\]{}*+?\\\\]")); 
    const std::wstring rep(_T("\\\\&")); 
    std::wstring result = regex_replace(string_to_escape, re_boostRegexEscape, rep, boost::match_default | boost::format_sed); 
    return result; 
} 

Para la versión ASCII, el uso std::string/boost::regex en lugar de std::wstring/boost::wregex.

Cuestiones relacionadas