C ++ Mac OS X regex(“.*")与regex_replace()导致无限循环 [英] c++ mac os x regex(".*") causes infinite loop with regex_replace()

查看:96
本文介绍了C ++ Mac OS X regex(“.*")与regex_replace()导致无限循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这会导致无限循环:

std::regex_replace("the string", std::regex(".*"), "whatevs");

这不会导致无限循环:

std::regex_replace("the string", std::regex("^.*$"), "whatevs");

Mac regex实施有什么问题?使用Mac OS X El Capitan Xcode 7.1

What is wrong with Mac regex implementation? using Mac OS X El Capitan Xcode 7.1

此问题与以下内容有关:

this question is related to: C++ Mac OS infinite loop in regex_replace if given blank regex expression

推荐答案

.*首先匹配整个字符串,然后匹配空字符串,因为*表示"匹配0个或更多匹配项"前面的子模式".空字符串匹配可能是无限循环的原因,但是我不确定这是错误还是设计错误.

The .* matches the whole string first, and then the empty string at the end because * means "match 0 or more occurrences of the preceding subpattern". The empty string match is probably the cause of the infinite loop, but I'm not sure whether it's a bug or by-design.

您可以使用std::regex_constants::match_not_null覆盖行为(请参见 regex_replace c ++参考):

You can override the behavior using std::regex_constants::match_not_null (see regex_replace c++ reference):

match_not_null 不为空空序列不匹配.

C ++代码演示仅返回whatevs:

std::regex reg(".*");
std::string s = "the string";
std::cout << std::regex_replace(s, reg, "whatevs",    
         std::regex_constants::match_not_null) << std::endl;

请注意,您观察到的无限循环"很可能是一个错误,因为源代码暗示一旦将空字符串传递给regex引擎,就应该引发异常.它尚未记录在任何地方.我认为(不确定)问题可能出在为替换操作收集匹配项时regex_replace方法如何处理字符串.

Note that the "infinite loop" you observe is most likely a bug since the source code hints that an exception should be thrown once an empty string is passed to the regex engine. It is not yet logged anywhere. I think (not sure) the issue might be with how the string is handled by the regex_replace method when matches are collected for a replace operation.

发生了什么事:regex_replace调用

basic_string<_Elem, _Traits1, _Alloc1> regex_replace(const basic_string<_Elem, _Traits1, _Alloc1>& _Str, const basic_regex<_Elem, _RxTraits>& _Re, const _Elem *_Ptr, regex_constants::match_flag_type _Flgs = regex_constants::match_default)
{   // search and replace, string result, string target, NTBS format
    basic_string<_Elem, _Traits1, _Alloc1> _Res;
    const basic_string<_Elem> _Fmt(_Ptr);
    regex_replace(_STD back_inserter(_Res), _Str.begin(), _Str.end(),
        _Re, _Fmt, _Flgs);
    return (_Res);
}

_Res是一个空字符串,_Fmt现在是 whatevs .然后,调用regex_replace. _Str.end()等于10,并初始化了一个指针.

_Res is an empty string, _Fmt is now whatevs. Then, the regex_replace is called. _Str.end() equals 10, and a pointer is initialized.

_First等于字符串,而_Last等于空字符串.

_First equals the string and _Last equals an empty string.

它是内部char缓冲区处理的结果,其指针实际上包含以下数组:

It happens as a result of internal char buffer processing whose pointer actually contains an array of:

inline back_insert_iterator<_Container> back_inserter(_Container& _Cont)方法首先从前0到9个字符中创建一个字符串,然后从10到15个数组元素(以空终止符开头的一个)中创建一个字符串.

The inline back_insert_iterator<_Container> back_inserter(_Container& _Cont) method first creates a string out of the first 0 to 9 chars, and then from 10 to 15 array elements (the one starting with the null terminator).

这篇关于C ++ Mac OS X regex(“.*")与regex_replace()导致无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆