c++ - rusa - guerra en siria hoy
¿Gcc 4.8 o anterior tiene fallos sobre expresiones regulares? (3)
Detección de funciones
Este es un fragmento para detectar si la implementación libstdc++
se implementa con preprocesador C define:
#include <regex>
#if __cplusplus >= 201103L && /
(!defined(__GLIBCXX__) || (__cplusplus >= 201402L) || /
(defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || /
defined(_GLIBCXX_REGEX_STATE_LIMIT) || /
(defined(_GLIBCXX_RELEASE) && /
_GLIBCXX_RELEASE > 4)))
#define HAVE_WORKING_REGEX 1
#else
#define HAVE_WORKING_REGEX 0
#endif
Macros
-
_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT
se defined enbits/regex.tcc
en4.9.x
-
_GLIBCXX_REGEX_STATE_LIMIT
se defined enbits/regex_automatron.h
en5+
-
_GLIBCXX_RELEASE
se agregó a7+
como resultado de esta respuesta y es la versión principal de GCC
Pruebas
Puedes probarlo con GCC de la siguiente manera:
cat << EOF | g++ --std=c++11 -x c++ - && ./a.out
#include <regex>
#if __cplusplus >= 201103L && /
(!defined(__GLIBCXX__) || (__cplusplus >= 201402L) || /
(defined(_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT) || /
defined(_GLIBCXX_REGEX_STATE_LIMIT) || /
(defined(_GLIBCXX_RELEASE) && /
_GLIBCXX_RELEASE > 4)))
#define HAVE_WORKING_REGEX 1
#else
#define HAVE_WORKING_REGEX 0
#endif
#include <iostream>
int main() {
const std::regex regex(".*");
const std::string string = "This should match!";
const auto result = std::regex_search(string, regex);
#if HAVE_WORKING_REGEX
std::cerr << "<regex> works, look: " << std::boolalpha << result << std::endl;
#else
std::cerr << "<regex> doesn''t work, look: " << std::boolalpha << result << std::endl;
#endif
return result ? EXIT_SUCCESS : EXIT_FAILURE;
}
EOF
Resultados
Aquí hay algunos resultados para varios compiladores:
$ gcc --version
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ ./a.out
<regex> doesn''t work, look: false
$ gcc --version
gcc (GCC) 6.2.1 20160830
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ ./a.out
<regex> works, look: true
$ gcc --version
gcc (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ ./a.out
<regex> works, look: true
$ gcc --version
gcc (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ ./a.out
<regex> works, look: true
$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ ./a.out
<regex> works, look: true
$ gcc --version
gcc (GCC) 6.2.1 20160830
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ clang --version
clang version 3.9.0 (tags/RELEASE_390/final)
Target: x86_64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
$ ./a.out # compiled with ''clang -lstdc++''
<regex> works, look: true
Aquí hay dragones
Esto no se admite por completo y se basa en la detección de macros privadas que los desarrolladores de GCC han puesto en los encabezados bits/regex*
. Podrían cambiar y desaparecer en cualquier momento . Con suerte, no se eliminarán en las versiones actuales 4.9.x, 5.x, 6.x, pero podrían desaparecer en las versiones 7.x.
Si los desarrolladores de GCC añadieron #define _GLIBCXX_HAVE_WORKING_REGEX 1
(o algo así como sugerencia de sugerencia), en la versión 7.x que persistía, este fragmento podría actualizarse para incluir eso y las versiones posteriores de GCC funcionarían con el fragmento anterior.
Por lo que yo sé, todos los demás compiladores tienen un <regex>
cuando __cplusplus >= 201103L
pero YMMV.
Obviamente, esto se rompería por completo si alguien definiera las macros _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT
o _GLIBCXX_REGEX_STATE_LIMIT
fuera de los stdc++-v3
de stdc++-v3
.
Estoy tratando de usar std :: regex en un código de C ++ 11, pero parece que el soporte es un poco problemático. Un ejemplo:
#include <regex>
#include <iostream>
int main (int argc, const char * argv[]) {
std::regex r("st|mt|tr");
std::cerr << "st|mt|tr" << " matches st? " << std::regex_match("st", r) << std::endl;
std::cerr << "st|mt|tr" << " matches mt? " << std::regex_match("mt", r) << std::endl;
std::cerr << "st|mt|tr" << " matches tr? " << std::regex_match("tr", r) << std::endl;
}
productos:
st|mt|tr matches st? 1
st|mt|tr matches mt? 1
st|mt|tr matches tr? 0
cuando se compila con gcc (MacPorts gcc47 4.7.1_2) 4.7.1, ya sea con
g++ *.cc -o test -std=c++11
g++ *.cc -o test -std=c++0x
o
g++ *.cc -o test -std=gnu++0x
Además, la expresión regular funciona bien si solo tengo dos patrones alternativos, por ejemplo, st|mt
, por lo que parece que el último no coincide por alguna razón. El código funciona bien con el compilador Apple LLVM.
¿Alguna idea sobre cómo resolver el problema?
Actualizar una posible solución es usar grupos para implementar múltiples alternativas, por ej. (st|mt)|tr
.
En este momento (usando std = c ++ 14 en g ++ (GCC) 4.9.2) todavía no acepta regex_match.
Aquí hay un enfoque que funciona como regex_match pero que usa sregex_token_iterator en su lugar. Y funciona con g ++.
string line="1a2b3c";
std::regex re("(//d)");
std::vector<std::string> inVector{
std::sregex_token_iterator(line.begin(), line.end(), re, 1), {}
};
//prints all matches
for(int i=0; i<inVector.size(); ++i)
std::cout << i << ":" << inVector[i] << endl;
imprimirá 1 2 3
Puede leer la referencia sregex_token_iterator en: http://en.cppreference.com/w/cpp/regex/regex_token_iterator
<regex>
fue implementado y lanzado en GCC 4.9.0.
En su versión (anterior) de GCC, no está implementado .
Ese código <regex>
prototipo se agregó cuando todo el soporte de C ++ 0x de GCC era altamente experimental, rastreaba borradores iniciales de C ++ 0x y estaba disponible para que las personas experimentaran. Eso permitió a las personas a encontrar problemas y dar su opinión al comité estándar antes de que se finalizara el estándar. En ese momento, muchas personas estaban agradecidas de haber tenido acceso a las características de punta de fábrica mucho antes de que C ++ 11 estuviera terminado y antes de que muchos otros compiladores proporcionaran soporte, y esa retroalimentación realmente ayudó a mejorar C ++ 11. Esta fue una buena cosa TM .
El código <regex>
nunca estuvo en un estado útil, pero se agregó como un trabajo en progreso como muchos otros bits de código en ese momento. Fue registrado y puesto a disposición para que otros colaboraran si quisieran, con la intención de que finalmente se terminara.
Así es como funciona el código abierto: Libere pronto, libere a menudo ; desafortunadamente en el caso de <regex>
solo conseguimos la parte inicial correcta y no la parte que a menudo habría terminado la implementación.
La mayoría de las partes de la biblioteca eran más completas y ahora están casi completamente implementadas, pero <regex>
no lo habían estado, por lo que se mantuvieron en el mismo estado sin terminar desde que se agregaron.
En serio, ¿quién pensó que enviar una implementación de regex_search que solo devolviera "false" era una buena idea?
No fue tan mala idea hace unos años, cuando C ++ 0x todavía era un trabajo en progreso y enviamos muchas implementaciones parciales. Nadie pensó que permanecería inutilizable por tanto tiempo, en retrospectiva, tal vez debería haber sido deshabilitado y requería una opción macro o incorporada para habilitarlo. Pero ese barco navegó hace mucho tiempo. Hay símbolos exportados de la biblioteca libstdc ++. So que dependen del código regex, por lo que simplemente eliminarlo (en, por ejemplo, GCC 4.8) no habría sido trivial.