std::regex_replace 字符串包含 \0 时的错误
std::regex_replace bug when string contains \0
我可能在 std::regex_replace
中发现了一个错误。
下面的代码应该写 "1a b2"
长度为 5,但它写 "1a2"
长度为 3。
我说的对吗?如果不是,为什么不呢?
#include <iostream>
#include <regex>
using namespace std;
int main()
{
string a = regex_replace("1<sn>2", std::regex("<sn>"), string("a[=11=]b", 3));
cout << "a: " << a << "\n";
cout << a.length();
return 0;
}
这似乎是 libstdc++ 中的错误。我使用调试器进入了 regex_replace
,直到到达这一部分:
// std [28.11.4] Function template regex_replace
/**
* @brief Search for a regular expression within a range for multiple times,
and replace the matched parts through filling a format string.
* @param __out [OUT] The output iterator.
* @param __first [IN] The start of the string to search.
* @param __last [IN] One-past-the-end of the string to search.
* @param __e [IN] The regular expression to search for.
* @param __fmt [IN] The format string.
* @param __flags [IN] Search and replace policy flags.
*
* @returns __out
* @throws an exception of type regex_error.
*/
template<typename _Out_iter, typename _Bi_iter,
typename _Rx_traits, typename _Ch_type,
typename _St, typename _Sa>
inline _Out_iter
regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last,
const basic_regex<_Ch_type, _Rx_traits>& __e,
const basic_string<_Ch_type, _St, _Sa>& __fmt,
regex_constants::match_flag_type __flags
= regex_constants::match_default)
{
return regex_replace(__out, __first, __last, __e, __fmt.c_str(), __flags);
}
引用 this write-up at cppreference.com,这似乎是在实现第一个重载,即采用 std::string
作为替换字符串的重载,方法是调用其 c_str()
然后调用第二个重载,采用 const char *
参数的参数,用于实际实现。这解释了观察到的行为。我找不到任何需要这种方法的东西。
进一步进入实际实施:
auto __len = char_traits<_Ch_type>::length(__fmt);
__out = __i->format(__out, __fmt, __fmt + __len, __flags);
因此,它确定替换字符串的长度并将替换字符串作为开始和结束迭代器传递到 format()
。
这似乎应该反过来,将 __fmt
保留为 std::basic_string
,并将直接派生自它的迭代器传递给 format()
.
我可能在 std::regex_replace
中发现了一个错误。
下面的代码应该写 "1a b2"
长度为 5,但它写 "1a2"
长度为 3。
我说的对吗?如果不是,为什么不呢?
#include <iostream>
#include <regex>
using namespace std;
int main()
{
string a = regex_replace("1<sn>2", std::regex("<sn>"), string("a[=11=]b", 3));
cout << "a: " << a << "\n";
cout << a.length();
return 0;
}
这似乎是 libstdc++ 中的错误。我使用调试器进入了 regex_replace
,直到到达这一部分:
// std [28.11.4] Function template regex_replace
/**
* @brief Search for a regular expression within a range for multiple times,
and replace the matched parts through filling a format string.
* @param __out [OUT] The output iterator.
* @param __first [IN] The start of the string to search.
* @param __last [IN] One-past-the-end of the string to search.
* @param __e [IN] The regular expression to search for.
* @param __fmt [IN] The format string.
* @param __flags [IN] Search and replace policy flags.
*
* @returns __out
* @throws an exception of type regex_error.
*/
template<typename _Out_iter, typename _Bi_iter,
typename _Rx_traits, typename _Ch_type,
typename _St, typename _Sa>
inline _Out_iter
regex_replace(_Out_iter __out, _Bi_iter __first, _Bi_iter __last,
const basic_regex<_Ch_type, _Rx_traits>& __e,
const basic_string<_Ch_type, _St, _Sa>& __fmt,
regex_constants::match_flag_type __flags
= regex_constants::match_default)
{
return regex_replace(__out, __first, __last, __e, __fmt.c_str(), __flags);
}
引用 this write-up at cppreference.com,这似乎是在实现第一个重载,即采用 std::string
作为替换字符串的重载,方法是调用其 c_str()
然后调用第二个重载,采用 const char *
参数的参数,用于实际实现。这解释了观察到的行为。我找不到任何需要这种方法的东西。
进一步进入实际实施:
auto __len = char_traits<_Ch_type>::length(__fmt);
__out = __i->format(__out, __fmt, __fmt + __len, __flags);
因此,它确定替换字符串的长度并将替换字符串作为开始和结束迭代器传递到 format()
。
这似乎应该反过来,将 __fmt
保留为 std::basic_string
,并将直接派生自它的迭代器传递给 format()
.