Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ GCC4.8或更早版本是否存在关于正则表达式的错误?_C++_Regex_Gcc_C++11_Libstdc++ - Fatal编程技术网

C++ GCC4.8或更早版本是否存在关于正则表达式的错误?

C++ GCC4.8或更早版本是否存在关于正则表达式的错误?,c++,regex,gcc,c++11,libstdc++,C++,Regex,Gcc,C++11,Libstdc++,我试图在一段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

我试图在一段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;
}
使用gcc(MacPorts gcc47 4.7.1_2)4.7.1编译时,可以使用

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

此外,如果我只有两种可选模式,例如,
st | mt
,那么正则表达式工作得很好,因此由于某些原因,最后一种模式似乎不匹配。该代码与Apple LLVM编译器配合良好

关于如何解决这个问题有什么想法吗

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

在GCC 4.9.0中实现并发布。

在您的(旧)GCC版本中,它是

该原型
代码是在GCC的所有C++0x支持都是高度实验性的时候添加的,跟踪早期的C++0x草案,并提供给人们进行实验。这使得人们能够在标准最终确定之前发现问题并向标准委员会提供反馈。当时,很多人都很感激在C++11完成之前以及在许多其他编译器提供任何支持之前很久就已经能够访问最前沿的功能,而这些反馈确实帮助改进了C++11。这是件好事

代码从未处于有用的状态,而是像当时的许多其他代码位一样作为正在进行的工作添加。它被签入并提供给其他人,如果他们愿意的话,可以进行协作,目的是最终完成它

开源通常就是这样工作的:——不幸的是,在
的例子中,我们只正确地完成了早期部分,而没有完成实现的经常部分

库的大多数部分都比较完整,现在几乎完全实现了,但是
还没有实现,所以它自添加以来一直处于未完成状态


但说真的,谁认为发布一个只返回“false”的regex_搜索实现是个好主意

这在几年前还不是一个坏主意,当时C++0x仍在开发中,我们提供了很多部分实现。没有人认为它会在这么长时间内不可用,所以事后看来,也许它应该被禁用,并且需要一个宏或构建时选项来启用它。但是那艘船很久以前就开航了。有从libstdc++导出的符号。所以库依赖于正则表达式代码,所以简单地删除它(比如在GCC 4.8中)并不是件小事。

Feature Detection 这是一个用于检测
libstdc++
实现是否使用C预处理器定义实现的代码段:

#包括
#如果uu cplusplus>=201103L&&\
(!已定义(uuu GLIBCXX_uuuuuuuuuuuuxx|||(uuu cplusplus>=201402L)|\
(定义(_GLIBCXX_REGEX_DFS_量词_LIMIT)|\
已定义(_GLIBCXX_REGEX_STATE_LIMIT)|\
(定义(_GLIBCXX_发布)和\
_GLIBCXX_发布>4)
#定义HAVE_WORKING_REGEX 1
#否则
#定义HAVE_WORKING_REGEX 0
#恩迪夫
  • \u GLIBCXX\u REGEX\u DFS\u限定符
    位于
    bits/REGEX.tcc
    中的
    4.9.x
  • \u GLIBCXX\u REGEX\u STATE\u LIMIT
    位于
    位/REGEX\u automatron.h
    位于
    5+
  • \u GLIBCXX\u发行版
    是作为的结果添加到
    7+
    ,是GCC的主要版本
测试 您可以使用GCC对其进行如下测试:

cat=201103L&&\
(!已定义(uuu GLIBCXX_uuuuuuuuuuuuxx|||(uuu cplusplus>=201402L)|\
(定义(_GLIBCXX_REGEX_DFS_量词_LIMIT)|\
已定义(_GLIBCXX_REGEX_STATE_LIMIT)|\
(定义(_GLIBCXX_发布)和\
_GLIBCXX_发布>4)
#定义HAVE_WORKING_REGEX 1
#否则
#定义HAVE_WORKING_REGEX 0
#恩迪夫
#包括
int main(){
常量std::regex regex(“.”);
const std::string string=“这应该匹配!”;
const auto result=std::regex_search(字符串,regex);
#如果你有工作经验
标准::cerr=201103L
但YMMV

显然,如果有人在
stdc++-v3
头之外定义了
\u GLIBCXX\u REGEX\u DFS\u量词\u LIMIT
\u GLIBCXX\u REGEX\u STATE\u LIMIT
宏,那么这将完全破坏。

此时(在g++(GCC)4.9.2中使用std=c++14)仍然不接受REGEX\u匹配

这里有一种类似于regex_match的方法,但使用sregex_token_迭代器

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;
string line=“1a2b3c”;
std::regex re(“(\\d)”);
向量反射器{
std::sregex_令牌_迭代器(line.begin(),line.end(),re,1),{}
};
//打印所有匹配项

对于(int i=0;iYes libstdc++)的
支持不完整。我们能为您提供什么帮助?对于libstdc++中
regex
的状态,请认真查看,谁认为发布一个只返回false的regex_搜索实现是个好主意?“哦,我们记录了它”似乎是一个软弱的回答。@AK4749:这不是一个错误。它只是完全没有实现。尽管这个问题出现的次数令人震惊,特别是在过去3-4年里,libstdc++
没有任何变化(例如:它仍然没有实现)@KeithThompson,虽然
确实是由libstdc++(GCC标准库)提供的,而不是
GCC
(编译器前端),但它是GCC(项目)的一部分。请参阅。如果您的发行版选择将其拆分为一个与GCC无关的单独包。非常好!我建议您从GCC 4.9中新增的一个标头中检查标头保护宏,但它们没有保护:-\GCC 7的宏没有更改,但理论上它们可以用于GCC 8+,因此请提交一个enh请求类似于
\u GLIBCXX的内容时的取消请求
g++ *.cc -o test -std=gnu++0x
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;