c++ - ¿Diferencia entre regex_match y regex_search?
gcc g++ (4)
Estaba experimentando con expresiones regulares al intentar responder a esta pregunta , y encontré que mientras regex_match
encuentra una coincidencia, regex_search
no.
El siguiente programa fue compilado con g ++ 4.7.1:
#include <regex>
#include <iostream>
int main()
{
const std::string s = "/home/toto/FILE_mysymbol_EVENT.DAT";
std::regex rgx(".*FILE_(.+)_EVENT//.DAT.*");
std::smatch match;
if (std::regex_match(s.begin(), s.end(), rgx))
std::cout << "regex_match: match/n";
else
std::cout << "regex_match: no match/n";
if (std::regex_search(s.begin(), s.end(), match, rgx))
std::cout << "regex_search: match/n";
else
std::cout << "regex_search: no match/n";
}
Salida:
regex_match: match regex_search: no match
¿Supongo que ambos deben coincidir mal o podría haber un problema con la biblioteca en GCC 4.7.1?
Al regex_search
el último código fuente de libstdc ++ para regex_search
, encontrará:
* @todo Implement this function.
Desafortunadamente, este no es el único artículo TODO que queda. La implementación <regex>
GCC está actualmente incompleta. Recomiendo usar Boost o Clang y #ifdef
el código hasta que GCC se #ifdef
al día.
(Esto tampoco se ha corregido en la rama 4.8).
Intenté usar la biblioteca de expresiones regulares en C ++ 11 y tuve muchos problemas (ambos usando g ++ 4.6 y 4.7). Básicamente, el soporte no está allí o solo hay un soporte parcial. Eso es cierto incluso para la versión SVN. Aquí tiene un enlace que describe el estado actual de la versión SVN de libstdc ++ .
Por el momento, supongo que la mejor opción es continuar utilizando Boost.Regex .
Alternativamente, puedes intentar usar libc++ . Según este documento , el soporte para expresiones regulares está completo.
Su expresión regular funciona bien (ambas coincidencias, que es correcta) en VS 2012rc.
En g ++ 4.7.1 (-std=gnu++11)
, si usa:
-
".*FILE_(.+)_EVENT//.DAT.*"
,regex_match
coincide, peroregex_search
no. -
".*?FILE_(.+?)_EVENT//.DAT.*"
, Niregex_match
niregex_search
concuerdan (O_o).
Todas las variantes deben coincidir, pero algunas no (por razones que ya han sido señaladas por betabandido ). En g ++ 4.6.3 (-std=gnu++0x)
, el comportamiento es idéntico a g ++ 4.7.1.
Boost (1.50) hace coincidir todo correctamente con ambas variedades de patrones.
Resumen :
regex_match regex_search ----------------------------------------------------- g++ 4.6.3 linux OK/- - g++ 4.7.1 linux OK/- - vs 2010 OK OK vs 2012rc OK OK boost 1.50 win OK OK boost 1.50 linux OK OK -----------------------------------------------------
Respecto a tu patrón, si te refieres a un carácter de punto ''.''
, entonces deberías escribir asi ( "//."
). También puede reducir el retroceso mediante el uso de modificadores no codiciosos ( ?
):
".*?FILE_(.+?)_EVENT//.DAT.*"
Suponiendo que C ++ y Boost Regex tienen una estructura y funcionalidad similares, la diferencia entre regex_match
y regex_search
se explica here :
El algoritmo
regex_match()
solo reportará el éxito si la expresión regular coincide con toda la entrada, de principio a fin. Si la expresión regular solo coincide con una parte de la entrada,regex_match()
devolverá false. Si desea buscar a través de la cadena buscando sub-cadenas que coincidan con lasregex_search()
regulares, use el algoritmoregex_search()
.