tun*_*nuz 98 c++ regex gcc libstdc++ c++11
我试图在C++ 11代码中使用std :: regex,但看起来支持有点儿错误.一个例子:
#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;
}
Run Code Online (Sandbox Code Playgroud)
输出:
st|mt|tr matches st? 1
st|mt|tr matches mt? 1
st|mt|tr matches tr? 0
Run Code Online (Sandbox Code Playgroud)
当使用gcc(MacPorts gcc47 4.7.1_2)4.7.1编译时,使用
g++ *.cc -o test -std=c++11
g++ *.cc -o test -std=c++0x
Run Code Online (Sandbox Code Playgroud)
要么
g++ *.cc -o test -std=gnu++0x
Run Code Online (Sandbox Code Playgroud)
此外,如果我只有两种替代模式st|mt,那么正则表达式效果很好,例如,看起来最后一种模式由于某些原因而不匹配.该代码适用于Apple LLVM编译器.
有关如何解决问题的任何想法?
更新一个可能的解决方案是使用组来实现多个替代方案,例如(st|mt)|tr.
Jon*_*ely 161
<regex> 在GCC 4.9.0中实施并发布.
在您的(较旧)版本的GCC中,它未实现.
<regex>当所有GCC的C++ 0x支持都是高度实验性的时候添加了原型代码,跟踪早期的C++ 0x草案并且可供人们试用.这使得人们能够在标准最终确定之前发现问题并向标准委员会提供反馈.当时很多人都很感激在C++ 11完成之前和许多其他编译器提供任何支持之前已经获得了前沿功能,并且这些反馈确实有助于改进C++ 11.这是一件好事TM.
该<regex>代码从来没有在一个有用的状态,但加入作为工作正在进行象当时的代码中的许多其他位.如果他们愿意的话,它已经过检查并可供其他人合作,目的是最终完成.
这通常是开源的工作方式:早期发布,经常发布 - 不幸的是,<regex>我们只得到了早期部分,而不是通常完成实施的部分.
图书馆的大多数部分都比较完整,现在几乎完全实现了,但是<regex>没有,所以它自添加以来一直保持在同一个未完成的状态.
但是,严肃地说,虽然运送regex_search的实现只是"返回false"是一个好主意?
几年前,当C++ 0x仍在进行中并且我们发布了大量部分实现时,这并不是一个坏主意.没有人认为它会长时间无法使用,事后看来,它可能已被禁用并需要一个宏或内置时间选项才能启用它.但那艘船早就航行了.libstdc ++中有导出的符号.所以依赖于正则表达式代码的库,所以简单地删除它(比方说,GCC 4.8)并不是一件容易的事.
Mat*_*son 11
这是一个片段,用于检测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
Run Code Online (Sandbox Code Playgroud)
_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT被定义在bits/regex.tcc在4.9.x_GLIBCXX_REGEX_STATE_LIMIT被定义在bits/regex_automatron.h在5+_GLIBCXX_RELEASE7+由于这个答案而被加入,并且是GCC的主要版本您可以使用GCC进行测试,如下所示:
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
Run Code Online (Sandbox Code Playgroud)
以下是各种编译器的一些结果:
$ 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
Run Code Online (Sandbox Code Playgroud)
$ 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
Run Code Online (Sandbox Code Playgroud)
$ 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
Run Code Online (Sandbox Code Playgroud)
$ 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
Run Code Online (Sandbox Code Playgroud)
$ 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
Run Code Online (Sandbox Code Playgroud)
$ 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
Run Code Online (Sandbox Code Playgroud)
这完全不受支持,并且依赖于GCC开发人员在bits/regex*标头中检测到的私有宏.他们可以改变,走在任何时间.希望它们不会在当前的4.9.x,5.x,6.x版本中删除,但它们可能会在7.x版本中消失.
如果GCC开发人员#define _GLIBCXX_HAVE_WORKING_REGEX 1在持续存在的7.x版本中添加了(或其他东西,提示提示nudge nudge),则可以更新此代码段以包含该代码段,以后的GCC版本将与上面的代码段一起使用.
据我所知,所有其他的编译器有一个工作<regex>时__cplusplus >= 201103L,但情况因人而异.
显然,如果有人在标题之外定义了_GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT或_GLIBCXX_REGEX_STATE_LIMIT宏,这将完全破坏stdc++-v3.