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