我想将一串整数对解析为数字。我使用这段代码:
#include <iostream>
#include <boost/regex.hpp>
int main()
{
boost::regex reg( "(\\d+):(\\d+)" );
std::string test = "1:2 3:4 5:6";
boost::sregex_token_iterator end;
for( boost::sregex_token_iterator i( test.begin(), test.end(), reg ); i != end; ++i ) {
boost::smatch what;
if( boost::regex_match( i->str(), what, reg ) )
std::cout << "found: \"" << what[1].str() << "\":\"" << what[2].str() << "\"" << std::endl;
}
return 0;
}
预期产出:
found: "1":"2"
found: "3":"4"
found: "5":"6"
我用gcc 4.7.2编译的boost 1.52得到了什么:
found: "2":"2"
found: "4":"4"
found: "6":"6"
提升1.52铿锵3.2:
found: "":"2"
found: "":"4"
found: "":"6"
我的代码出了什么问题?
答案 0 :(得分:4)
感谢弗雷泽的提示,一个可能的解决方案是:
for( boost::sregex_token_iterator i( test.begin(), test.end(), reg ); i != end; ++i ) {
boost::smatch what;
const std::string &str = i->str();
if( boost::regex_match( str, what, reg ) )
std::cout << "found: \"" << what[1].str() << "\":\"" << what[2].str() << "\"" << std::endl;
}
问题来自于i-&gt; str()调用boost :: sub_match方法的事实:
basic_string<value_type> str()const;
并按值返回std :: string。因此传递给regex_match和boost :: smatch对象的临时std :: string实际上会记住原始字符串中的位置,这实际上是在boost :: regex_match完成后销毁的。 类似的问题可以复制如下:
std::string function();
boost::smatch what;
if( boost::regex_match( function(), what, reg ) ) ...
或者我相信这样的代码也很脆弱:
boost::smatch what;
if( boost::regex_match( std::string( "abc" ), what, reg ) ) ...
我不确定在编译时如何防止这种情况,应该将其视为错误。 std :: regex_match似乎有相同的签名,那里存在这个问题吗?
答案 1 :(得分:3)
我不知道Boost现在有什么细节,但我不认为这会影响到这一点。我也不知道为什么你在调用regex_match
之后得到了时髦的结果,但这不是必需的; token_iterator
已经完成了那场比赛,所以你需要的只是
std::cout << (*i)[1].str() << ':' << (*i)[2].str() << std::endl;
或者,如果您愿意:
std::cout << i->str(1) << ':' << i->str(2) << std::endl;
请注意,这是C ++ 11。它也适用于Boost,但我还没有尝试过。
答案 2 :(得分:3)
我不确定Boost.Regex的实现细节,但似乎将sregex_token_iterator
循环内的解除引用的for
复制到临时std::string
可以解决问题:< / p>
std::string copied( i->str() );
boost::smatch what;
if( boost::regex_match( copied, what, reg ) ) {
std::cout << "found: \"" << what[1].str() << "\":\"" << what[2].str() << "\"" << std::endl;
}
希望有更好的Boost.Regex知识的人可以给出更好的答案。