C++ 正则表达式字符串捕获

5

试图让C++正则表达式字符串捕获正常工作。我尝试了Windows和Linux以及Boost和本地C++ 0x11的所有四种组合。示例代码如下:

#include <string>
#include <iostream>
#include <boost/regex.hpp>
//#include <regex>

using namespace std;
using namespace boost;

int main(int argc, char** argv)
{
    smatch sm1;
    regex_search(string("abhelloworld.jpg"), sm1, regex("(.*)jpg"));
    cout << sm1[1] << endl;
    smatch sm2;
    regex_search(string("hell.g"), sm2, regex("(.*)g"));
    cout << sm2[1] << endl;
}

最接近的可行方案是使用带有Boost (1.51.0)的g++ (4.7)。在这个版本中,第一个cout输出预期值abhelloworld。但第二个cout没有任何输出。
使用g++ 4.7、-std = gnu++11和<regex>而不是<boost/regex.hpp>并没有产生任何输出。
使用Visual Studio 2012原生<regex>会导致异常,表示字符串迭代器不兼容。
在Boost 1.51.0和<boost/regex.hpp>下,使用Visual Studio 2008会导致异常,表示“标准C++库无效参数”。
这些问题是由于C++ regex的错误,还是我做错了什么呢?
2个回答

9
在您发布这篇文章时,正如其他答案所述,gcc不支持<regex>现在已经支持)。至于其他问题,您的问题在于您正在传递临时字符串对象。将您的代码更改为以下内容:
smatch sm1;
string s1("abhelloworld.jpg");
regex_search(s1, sm1, regex("(.*)jpg"));
cout << sm1[1] << endl;
smatch sm2;
string s2("hell.g");
regex_search(s2, sm2, regex("(.*)g"));
cout << sm2[1] << endl;

你的原始示例编译成功是因为regex_search采用了const引用,临时对象可以绑定到它上面,但是,smatch只存储迭代器到您的临时对象中,而这个临时对象已经不存在了。解决方法是不要传递临时对象。
如果您查看C++标准[§ 28.11.3/5],您会发现以下内容:
返回:regex_search(s.begin(), s.end(), m, e, flags)的结果。
这意味着在内部仅使用对您传入的字符串的迭代器,因此,如果您传递一个临时对象,则将使用指向该临时对象的迭代器,这些迭代器无效,并且实际的临时对象本身未被存储

0

GCC目前不支持<regex>。请参考手册


3
从gcc4.9版本开始,支持C++11的<regex>。 - Nicolas Holthaus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接