c ++ mac os x regex(“。*”)导致regex_replace()

时间:2015-11-19 05:15:59

标签: c++ regex macos infinite-loop

这会导致无限循环:

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

这不会导致无限循环:

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

Mac正则表达式实现有什么问题?使用Mac OS X El Capitan Xcode 7.1

此问题与:C++ Mac OS infinite loop in regex_replace if given blank regex expression

有关

2 个答案:

答案 0 :(得分:2)

.*首先匹配整个字符串,然后匹配最后的空字符串,因为*表示“匹配0或更多出现的前一个子模式”。空字符串匹配可能是无限循环的原因,但我不确定它是错误还是设计。

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

  

match_not_null 非空空序列不匹配。

C++ code demo仅返回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_replace方法如何处理字符串。

以下是: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,并初始化指针。

_First等于字符串_Last等于空字符串。

enter image description here

它发生在内部字符缓冲区处理的结果中,其指针实际上包含一个数组:

enter image description here

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

答案 1 :(得分:0)

stribizhev的回答激发了这一点。以下是使用各种标志的示例结果:

GOOD

boost::regex_replace(input, match, replace, input.empty() ? boost::regex_constants::match_default : boost::regex_constants::match_not_null);

  

结果:

input:   ""
match:   ".*"
replace: "a"
output:  "a"

input:   "something"
match:   ".*"
replace: "a"
output:  "a"

BAD

boost::regex_replace(input, match, replace, boost::regex_constants::match_not_null);

  

结果:

input:   ""
match:   ".*"
replace: "a"
output:  ""

input:   "something"
match:   ".*"
replace: "a"
output:  "a"

BAD

boost::regex_replace(input, match, replace);

  

结果:

input:   ""
match:   ".*"
replace: "a"
output:  "a"

input:   "something"
match:   ".*"
replace: "a"
output:  "aa"