2011-01-30 7 views
7

Tengo problemas con la función de formato en boost::regex_replace. Puedo llamar a la versión de un parámetro de ella, pero no la de dos parámetros:Problemas con la función de formato de dos parámetros en boost :: regex_replace

e = "(^|>)([^<>]+)"; 
h_str = regex_replace(h_str, e, repl_quot, boost::match_default); 

Dónde repl_quot se define como

std::string const &repl_quot(boost::smatch const &what) { 
    boost::regex e("\""); 
    std::string repl("&#34;"); 
    static std::string; 
    str = regex_replace(what[0].str(), e, repl, boost::match_default); 
    return str; 
} 

Los trabajos anteriores, pero que realmente no quieren usar esa estática variables, así que traté de lo que pensaba era una versión alternativa de dos parámetros aceptables:

std::string const &repl_quot2(boost::smatch const &what, std::string &out) { 
    boost::regex e("\""); 
    std::string repl("&#34;"); 
    out = regex_replace(what[0].str(), e, repl, boost::match_default); 
    return out; 
} 

Pero regex_replace no aceptará esto (un error del compilador complicado). Estoy tratando de utilizar la versión de dos parámetros sobre la base de las siguientes opciones del Boost::Regex documentación:

plantilla basic_string regex_replace (const basic_string & s, const basic_regex & correo, formateador FMT, banderas match_flag_type = match_default);

requiere el tipo de formateador debe ser ya sea ... un funtor unario, binaria o ternaria que calcula la cadena de reemplazo de una llamada función: ya sea FMT (lo), que debe devolver un contenedor de char_type de para ser usado como texto de reemplazo, o ya sea fmt (what, out) o fmt (what, out, flags), que escriben el texto de reemplazo a * out, y luego devuelven la nueva posición OutputIterator . En cada caso, ¿cuál es el objeto match_results que representa la coincidencia encontrada?

Ha habido reiteradas solicitudes de la mensaje de error del compilador, por lo que aquí es (tener cuidado con lo que pides):

c: \ impulso \ impulso \ expresión regular \ v4 \ regex_format.hpp En la función miembro `OutputIter boost :: re_detail :: format_functor_container :: operator() (const Match &, OutputIter, boost :: regex_constants :: match_flag_type, const Traits &) [con OutputIter = boost :: re_detail :: string_out_iterator, std: : allocator>>, Container = const std :: string & (*) (const boost :: smatch &, std :: string &), coincide = Boost :: match_results < __gnu_cxx :: __ normal_iterator, std :: asignador>>, std :: asignador, std :: asignador>>>>>, Rasgos = impulso :: regex_traits_wrapper>>] ':

356 c : \ boost \ boost \ regex \ v4 \ match_results.hpp instanciado del formato 'OutputIterator boost :: match_results :: (OutputIterator, Functor, boost :: regex_constants :: match_flag_type, const RegexT &) const [con OutputIterator = boost :: re_detail :: string_out_iterator, std :: allocator>>, Functor = const std :: string & (*) (const boost :: smatch &, std :: string &), RegexT = boost :: basic_regex>>, BidiIterator = __gnu_cxx :: __ normal_iterator, std :: allocator>>, Allocator = std :: asignador, std :: asignador>>>>]'

60 c: \ impulso \ impulso \ expresión regular \ v4 \ regex_replace.hpp una instancia de `OutputIterator impulsar :: regex_replace (OutputIterator, BidirectionalIterator, BidirectionalIterator, const boost :: basic_regex &, Formatter, boost :: regex_constants :: match_flag_type) [with OutputIter ator = boost :: re_detail :: string_out_iterator, std :: allocator>>, BidirectionalIterator = __gnu_cxx :: __ normal_iterator, std :: allocator>>, traits = boost :: regex_traits>, charT = char, Formatter = const std :: string & (*) (const impulso :: smatch &, std :: string &)]'

80 c: \ impulso \ impulso \ expresión regular \ v4 \ regex_replace.hpp una instancia de `std :: basic_string, std :: asignador < _T2>> boost :: regex_replace (const std :: basic_string, std :: allocator < _T2>> &, const boost :: basic_regex &, Formatter, boost :: regex_constants :: match_flag_type) [with traits = boost :: regex_traits>, charT = char, Formatter = const std :: string & (*) (const boost :: smatch &, std :: string &)]'

327 C: \ Dev-Cpp \ Ejemplos \ WordRad \ xhtml_open.cpp crear instancias de aquí

1064 c: \ impulso \ impulso \ expresión regular \ v4 \ regex_format. solicitud de hpp para el miembro begin' in ((boost :: re_detail :: format_functor_container, std :: allocator>>, std :: allocator, std :: allocator>>>>>, boost :: regex_traits_wrapper>>> *) this) -> boost :: re_detail :: format_functor_container, std :: allocator>>, std :: allocator, std :: allocator>>>>>, boost :: regex_traits_wrapper>>> :: func ', que es de tipo no de clase ` const std :: string & (* const) (const boost :: smatch &, std :: string &) '

1064 c: \ boost \ boost \ regex \ v4 \ regex_format.hpp solicitud para el miembro end' in ((boost :: re_detail :: format_functor_container, std :: allocator>>, std :: allocator, std :: allocator> >>>>, boost :: regex_traits_wrapper>>> *) this) -> boost :: re_detail :: format_functor_container, std :: allocator>>, std :: allocator, std :: allocator>>>>>, boost: : regex_traits_wrapper>>> :: func 'que es del tipo no-clase `const std :: string & (* const) (const impulso :: smatch &, std :: string &)'

+0

Debería publicar el error que está recibiendo. –

+0

Es absurdamente largo. Predigo que no harías cara o cruz. Su plantilla relacionada o algo así. El problema es con qué regex-replace se espera como firma para el parámetro fmt, petate a templates o lo que sea. El mensaje de error es indescifrable. – Mark

+0

1064 c: \ boost \ boost \ regex \ v4 \ regex_format.hpp solicitud de miembro 'end 'en' ((boost :: re_detail :: formato_contenedor_del_fuente , std :: allocator >>, std :: allocator , std :: allocator >>>>>, boost :: regex_traits_wrapper >>> *) this) -> boost :: re_detail :: format_fu ... – Mark

Respuesta

1

OK así es como tuve que escribir repl_quot2:

struct formatter 
{  
    template<typename Out> 
    Out operator()(boost::smatch const &what, Out out) const { 
    boost::regex e("\"");  
    std::string repl("&#34;"); 
    std::string str 
     = regex_replace(what[0].str(), e, repl, boost::match_default); 
    out = std::copy(str.begin(), str.end(), out); 
    return out; 
    } 

}; 

Y luego cuando se invoca desde regex_replace:

e = "(^|>)[^<>]+"; 
    formatter repl_quot2; 
    h_str = regex_replace(h_str, e, repl_quot2, boost::match_default); 

Esto corresponde a la documentación en http://boost-sandbox.sourceforge.net/libs/xpressive/doc/html/boost_xpressive/user_s_guide/string_substitutions.html.

Lo que me desconcierta en este momento es que requiere un funtor (una clase con el operador()) en oposición a una función si se llama a la versión de dos parámetros, pero no requiere un funtor para las versiones de un parámetro (repl_quot en el OP). De todos modos, no he conseguido que la nueva versión de parm funcione como una función directa.Pero el problema principal fue out que tuve que pasar y devolver como un parámetro de plantilla como se muestra, en lugar de hacerlo std :: string como en el OP. Se supone que es un OutputIterator, aún no sé qué es eso realmente.

Por cierto, todo esto regex hace es reemplazar las comillas dobles con la versión de entidad html, \ & # 34; en cualquier texto en html que no forme parte de una etiqueta.

Además, la razón por la que quería reemplazar mi función original repl_quot es que tenía que almacenar el valor de retorno en una variable local estática en repl_quot. No funciona simplemente devolver una variable local normal, porque puede desasignarse antes de que pueda ser utilizada (y causar bloqueos). repl_quot estaba funcionando: mi problema con la estática es que no es seguro para subprocesos y no sabía si Boost :: RegEx tenía varios subprocesos. Creo que lo compilé como multithreading, pero la var estática no pareció causar problemas. Pero con repl_quot2 escribo el valor de retorno a un parámetro de salida.

Cuestiones relacionadas