是正则expression式的gcc 4.8或更早的车?

我正在尝试在C ++ 11代码中使用std :: regex,但看起来支持是有点bug。 一个例子:

#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; } 

输出:

 st|mt|tr matches st? 1 st|mt|tr matches mt? 1 st|mt|tr matches tr? 0 

当用gcc编译(MacPorts gcc47 4.7.1_2)4.7.1,用

 g++ *.cc -o test -std=c++11 g++ *.cc -o test -std=c++0x 

要么

 g++ *.cc -o test -std=gnu++0x 

此外,正则expression式工作得很好,如果我只有两种替代模式,例如st|mt ,所以看起来最后一个不匹配是由于某些原因。 该代码适用于Apple LLVM编译器。

关于如何解决这个问题的任何想法?

更新一个可能的解决scheme是使用组来实现多个选项,例如(st|mt)|tr

<regex>在GCC 4.9.0中实现并发布。

在你的GCC版本中,它没有被执行 。

当所有的GCC的C ++ 0x支持都是高度实验性的,追踪早期的C ++ 0x草案,并使其可供人们试用时,就添加了原型<regex>代码。 在标准制定之前,这让人们能够发现问题并向标准委员会提出反馈意见。 当时很多人在C ++ 11完成之前和其他许多编译器提供任何支持之前就已经获得了尖端的function,并且反馈确实帮助改进了C ++ 11。 这是一件好事TM

<regex>代码从来没有处于有用的状态,而是像当时许多其他代码一样被添加为正在进行的工作。 如果他们愿意的话,它被检查并提供给其他人合作,意图最终完成。

这往往是开源的工作原理: 早发布,经常发布 – 不幸的是,在<regex>的情况下,我们只得到早期部分权利,而不是通常会完成实施的部分。

图书馆的大部分地方都比较完整,现在几乎已经完全实施了,但是<regex>还没有完成,所以它在添加之后仍然处于未完成的状态。

认真的是,谁虽然运送一个regex_search的实现只是“返回false”是一个好主意?

几年前,C ++ 0x仍然是一个正在进行的工作,而且我们运行了大量的部分实现,这并不是什么坏主意。 没有人认为这么长时间以来,它一直是不可用的,事后看来,也许它应该已经被禁用了,需要一个macros观或者固定的选项来实现它。 但那艘船很早就航行了 从libstdc ++。so库中导出的符号依赖于正则expression式代码,所以简单地删除它(比如说GCC 4.8)就不会是微不足道的了。

特征检测

这是检测libstdc++实现是否使用C预处理器定义实现的一个片段:

 #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_LIMIT4.9.x bits/regex.tcc4.9.x
  • _GLIBCXX_REGEX_STATE_LIMIT bits/regex_automatron.h中定义为5+
  • _GLIBCXX_RELEASE已被添加到7+作为这个答案的结果,是GCC的主要版本

testing

你可以用这样的GCC来testing它:

 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 

结果

以下是各种编译器的一些结果:


 $ 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 

这里是龙

这是完全不受支持的,并依赖于检测到GCC开发人员将其放入bits/regex*头中的私有macros。 他们可以在任何时候改变和消失。 希望它们不会在当前的4.9.x,5.x,6.x版本中被删除,但是它们可以在7.x版本中消失。

如果GCC开发者在7.x版本中添加了#define _GLIBCXX_HAVE_WORKING_REGEX 1 (或者其他的东西,提示提示微移),那么这个代码片段可以被更新以包含这个代码,后来的GCC版本可以在上面的代码片段中使用。

据我所知,当__cplusplus >= 201103L但YMMV时,所有其他编译器都有一个工作的<regex>

显然,如果有人在stdc++-v3头文件之外定义了_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT_GLIBCXX_REGEX_STATE_LIMITmacros,这将彻底破坏。

此时(在g ++(GCC)4.9.2中使用std = c ++ 14)仍然不接受regex_match。

这是一种像regex_match一样的方法,但是使用sregex_token_iterator代替。 它和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; 

它会打印1 2 3

您可以阅读以下链接中的sregex_token_iterator参考: http ://en.cppreference.com/w/cpp/regex/regex_token_iterator