C++ 将临时std::string传递给boost::regex\u匹配
我想把一串整数对解析成数字。我使用以下代码:C++ 将临时std::string传递给boost::regex\u匹配,c++,regex,boost,C++,Regex,Boost,我想把一串整数对解析成数字。我使用以下代码: #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_iterat
#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;
}
我从gcc 4.7.2编译的boost 1.52中得到了什么:
found: "2":"2"
found: "4":"4"
found: "6":"6"
boost 1.52叮当声3.2:
found: "":"2"
found: "":"4"
found: "":"6"
我的代码出了什么问题?我不知道Boost现在有哪些细节,但我认为它不会影响这一点。我也不知道为什么在调用
regex_match
之后,你会得到令人不快的结果,但这不是必需的;token\u迭代器
已经完成了匹配,所以您只需要
std::cout << (*i)[1].str() << ':' << (*i)[2].str() << std::endl;
std::cout我不确定Boost.Regex的实现细节,但似乎将for
循环中的取消引用的sregex\u令牌迭代器
复制到临时std::string
可以解决问题:
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;
}
std::字符串已复制(i->str());
刺激:smatch什么;
if(boost::regex_匹配(复制,什么,注册)){
std::cout感谢弗雷泽的提示,一种可能的解决方案是:
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;
}
或者我认为这样的代码也很脆弱:
boost::smatch what;
if( boost::regex_match( std::string( "abc" ), what, reg ) ) ...
我不确定如何在编译时防止这种情况,是否应该将其视为一个bug。std::regex_match似乎具有相同的签名,是否存在此问题?错误:键入'boost::sregex_token_iterator'(也称为'regex_token_iterator')不提供下标运算符良好的捕获,谢谢!实际上不需要复制-常量引用就足够了。值得一提的是,在clang++/libc++中实现的std::regex
会打印预期的输出。@Cubbi它仍然可以是UB,除非他们更改smatch存储子表达式结果的方式std::r存在此问题egex也是如此,因为match_results
被定义为将迭代器保存到传递给regex_match
的字符串中,当它被解构时,迭代器将失效。
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;
}
basic_string<value_type> str()const;
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 ) ) ...