什么是使用迭代器接口的std :: regex_search复杂性的一致实现?

时间:2017-01-18 03:54:23

标签: c++ regex c++11 c++-standard-library

尽管c ++标准似乎没有明确保证或禁止它,但是std :: regex_search的某些实现似乎遍历整个输入,无论在哪里找到搜索成功。 (最小的工作示例是许多代码行,所以请耐心等待。)

考虑一个自定义的,符合要求的BidirectionalIterator类(称为FileContentsIter),它从FILE *中读取其输入,适当地缓存它所读取的内容,以便减量运算符正常工作,并在以下情况下比较等于默认构造的实例文件达到EOF。还假设正常的复制和赋值语义。

现在考虑使用此自定义迭代器类搜索与特定正则表达式匹配的序列的用例。假设输入文件包含:" abcdefghijk ..."正则表达式只是" c"。

致电:

std::regex exp("c");
std::match_results<BidirIt,Alloc> results;
FileContentsIter in(someFile);
bool found = std::regex_search(in, FileContentsIter(), results, exp);

found应返回true,match [0]应包含(in,FileContentsIter())并且match [1]应包含跨越&#34; c&#34;的迭代器范围。

这是正常的,并没有争议。我的问题集中在符合实现的复杂性上(这里是LLVM)。分析增量&#39; in上的运算符告诉我,即使正则表达式在第3个字符上匹配,整个文件仍被读取。

深入研究LLVM的实现,我看到了代码:

template <class _BidirectionalIterator, class _CharT, class _Traits>
inline _LIBCPP_INLINE_VISIBILITY
bool
regex_search(_BidirectionalIterator __first, _BidirectionalIterator __last,
             const basic_regex<_CharT, _Traits>& __e,
             regex_constants::match_flag_type __flags = regex_constants::match_default)
{
    basic_string<_CharT> __s(__first, __last);
    match_results<const _CharT*> __mc;
    return __e.__search(__s.data(), __s.data() + __s.size(), __mc, __flags);
}

请注意:

basic_string<_CharT> __s(__first, __last);

这基本上只是意味着实现将整个输入推送到std :: string并进行搜索。很容易看出,在需要逐步搜索内容的多兆字节或千兆字节文件的情况下,这可能会非常糟糕(例如,在词法分析器的情况下)。

这让我很惊讶。

所以我的问题是:这种行为是我缺少的标准的功能还是简单的&#34;简单&#34;实施?虽然除非有人回答LLVM实际上是不一致的,但我认为这并不重要,因为我需要使用不同的正则表达式库(或重构我的代码),以保证合理的增量行为。

提前致谢...

0 个答案:

没有答案