将临时std::string传递给boost::regex_match
Passing temporary std::string to boost::regex_match
我想将一串整数对解析为数字。我使用以下代码:
#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"
boost 1.52 clang 3.2
found: "":"2"
found: "":"4"
found: "":"6"
我的代码有什么问题?
感谢Fraser的提示,一个可能的解决方案是:
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->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似乎有相同的签名,是否存在这个问题?
我不确定Boost的实现细节。Regex,但似乎将for
循环内的解引用sregex_token_iterator
复制到临时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;
}
希望有人对Boost有更好的了解。
我不知道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一起工作,但我还没有尝试过。
相关文章:
- 使用 boost::regex 从目录中获取带有一些正则表达式的文件名称时出现意外输出
- 在VC2015U3上,std::regex比boost::regex慢得多
- 使用 boost::regex (c++) 比较两个正则表达式
- Build Boost Regex for Windows VS2013
- boost::regex 和std::regex之间的不一致?
- 尝试使用生成文件编译程序时"fatal error: boost/regex.hpp: No such file or directory" C++
- 带有Boost Regex库的未解决的外部对象
- boost::regex链接问题在Xcode 4.5.2中
- 如何检查使用哪个匹配组进行匹配(boost-regex)
- boost::regex和std::regex之间的不一致
- Boost.Regex parsing
- BOOST.REGEX定界器解析
- 以下等级表达式不适合Boost Regex
- 在Windows C 代码:: Blocks上的Boost Regex
- Boost Regex用于格式化MAC地址字符串
- 使用 c++/boost::regex 提取 HTML 文件的特定部分
- 使用 boost::regex 更改文件中数据的格式
- 在OS X上使用clang编译boost regex时发生链接错误
- boost regex空格后跟一个或多个星号
- Boost Regex中的命名子表达式错误