Estou tentando usar std :: regex em um pedaço de código C ++ 11, mas parece que o suporte é um pouco bugado. Um exemplo:
#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;
}
saídas:
st|mt|tr matches st? 1
st|mt|tr matches mt? 1
st|mt|tr matches tr? 0
quando compilado com gcc (MacPorts gcc47 4.7.1_2) 4.7.1, ou com
g++ *.cc -o test -std=c++11
g++ *.cc -o test -std=c++0x
ou
g++ *.cc -o test -std=gnu++0x
Além disso, o regex funciona bem se eu tiver apenas dois padrões alternativos, por exemplo st|mt
, parece que o último não é compatível por alguns motivos. O código funciona bem com o compilador LLVM da Apple.
Alguma ideia de como resolver o problema?
Atualizar uma solução possível é usar grupos para implementar alternativas múltiplas, por exemplo (st|mt)|tr
.
<regex>
suporte do libstdc ++ está incompleto. O que podemos ajudar você?regex
em libstdc ++, consulte gcc.gnu.org/onlinedocs/libstdc++/manual/…<regex>
nos últimos 3-4 anos (como em: ele permanece não implementado).<regex>
é fornecido pelo libstdc ++ (a biblioteca padrão do GCC) e nãogcc
(o front end do compilador), ele faz parte do GCC (o projeto). Consulte "libstdc ++ - v3 é desenvolvido e lançado como parte do GCC" . Se sua distro decidir dividi-lo em um pacote separado, isso não tem nada a ver com o GCC.Respostas:
<regex>
foi implementado e lançado no GCC 4.9.0.Em sua versão (mais antiga) do GCC, ele não está implementado .
Esse
<regex>
código de protótipo foi adicionado quando todo o suporte C ++ 0x do GCC era altamente experimental, rastreando os primeiros rascunhos C ++ 0x e sendo disponibilizado para que as pessoas experimentassem. Isso permitiu que as pessoas encontrassem problemas e dessem feedback ao comitê de padrão antes que o padrão fosse finalizado. Na época, muitas pessoas ficaram gratas por ter acesso a recursos de ponta muito antes da conclusão do C ++ 11 e antes que muitos outros compiladores fornecessem qualquer suporte, e esse feedback realmente ajudou a melhorar o C ++ 11. Este foi um Good Thing TM .O
<regex>
código nunca esteve em um estado útil, mas foi adicionado como um trabalho em andamento como muitos outros bits de código da época. Ele foi verificado e disponibilizado para que outras pessoas colaborassem, se quisessem, com a intenção de que acabasse eventualmente.Freqüentemente, é assim que o código aberto funciona: libere com antecedência, libere com frequência - infelizmente, no caso de
<regex>
apenas acertarmos a parte inicial e não a parte frequente que teria concluído a implementação.A maioria das partes da biblioteca estava mais completa e agora está quase totalmente implementada, mas
<regex>
não estava, então ela permaneceu no mesmo estado inacabado desde que foi adicionada.Não era uma ideia tão ruim alguns anos atrás, quando C ++ 0x ainda era um trabalho em andamento e nós distribuímos muitas implementações parciais. Ninguém pensou que permaneceria inutilizável por tanto tempo, então, olhando para trás, talvez devesse ter sido desativado e necessário uma macro ou opção de tempo embutido para ativá-lo. Mas aquele navio navegou há muito tempo. Existem símbolos exportados do libstdc ++. Portanto, a biblioteca que depende do código regex, portanto, simplesmente removê-lo (digamos, no GCC 4.8) não teria sido trivial.
fonte
Detecção de recursos
Este é um snippet para detectar se a
libstdc++
implementação é implementada com o pré-processador C define:Macros
_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT
é definida embits/regex.tcc
nas4.9.x
_GLIBCXX_REGEX_STATE_LIMIT
é definida embits/regex_automatron.h
nas5+
_GLIBCXX_RELEASE
foi adicionado7+
como resultado desta resposta e é a versão principal do GCCTestando
Você pode testá-lo com o GCC desta forma:
Resultados
Aqui estão alguns resultados para vários compiladores:
Aqui estão dragões
Isso é totalmente incompatível e depende da detecção de macros privadas que os desenvolvedores do GCC colocaram nos
bits/regex*
cabeçalhos. Eles podem mudar e ir embora a qualquer momento . Esperançosamente, eles não serão removidos nas versões 4.9.x, 5.x, 6.x atuais, mas podem desaparecer nas versões 7.x.Se os desenvolvedores do GCC adicionaram uma
#define _GLIBCXX_HAVE_WORKING_REGEX 1
(ou algo assim, dica dica nudge nudge) na versão 7.x que persistiu, este snippet poderia ser atualizado para incluir isso e versões posteriores do GCC funcionariam com o snippet acima.Pelo que eu sei, todos os outros compiladores têm uma função
<regex>
quando,__cplusplus >= 201103L
exceto YMMV.Obviamente, isso seria completamente quebrado se alguém definisse as macros
_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT
ou_GLIBCXX_REGEX_STATE_LIMIT
fora dosstdc++-v3
cabeçalhos.fonte
_GLIBCXX_REGEX_IS_OK_NOW_KTHXBAI
nos cabeçalhos, para que não seja esquecido - obrigado!No momento (usando std = c ++ 14 em g ++ (GCC) 4.9.2) ainda não está aceitando regex_match.
Aqui está uma abordagem que funciona como regex_match, mas usando sregex_token_iterator. E funciona com g ++.
vai imprimir 1 2 3
você pode ler a referência sregex_token_iterator em: http://en.cppreference.com/w/cpp/regex/regex_token_iterator
fonte
std::regex_search
entanto, você pode fazer isso com , consulte wandbox.org/permlink/rLbGyYcYGNsBWsaB