diff --git a/src/regex.hh b/src/regex.hh index 11926d644..7fda8f0b1 100644 --- a/src/regex.hh +++ b/src/regex.hh @@ -139,7 +139,7 @@ bool regex_search(It begin, It end, MatchResults& res, const Regex& re, String option_to_string(const Regex& re); void option_from_string(StringView str, Regex& re); -template +template struct RegexIterator { using ValueType = MatchResults; @@ -147,7 +147,8 @@ struct RegexIterator RegexIterator() = default; RegexIterator(Iterator begin, Iterator end, const Regex& re, RegexExecFlags flags = RegexExecFlags::None) - : m_regex{&re}, m_next_begin{begin}, m_begin{begin}, m_end{end}, m_flags{flags} + : m_regex{&re}, m_next_pos{direction == MatchDirection::Forward ? begin : end}, + m_begin{begin}, m_end{end}, m_flags{flags} { next(); } @@ -167,7 +168,7 @@ struct RegexIterator return true; return lhs.m_regex == rhs.m_regex and - lhs.m_next_begin == rhs.m_next_begin and + lhs.m_next_pos == rhs.m_next_pos and lhs.m_end == rhs.m_end and lhs.m_flags == rhs.m_flags and lhs.m_results == rhs.m_results; @@ -178,6 +179,9 @@ struct RegexIterator return not (lhs == rhs); } + RegexIterator begin() { return *this; } + RegexIterator end() { return {}; } + private: void next() { @@ -186,19 +190,31 @@ private: RegexExecFlags additional_flags{}; if (m_results.size() and m_results[0].first == m_results[0].second) additional_flags |= RegexExecFlags::NotInitialNull; - if (m_begin != m_next_begin) - additional_flags |= RegexExecFlags::NotBeginOfSubject | RegexExecFlags::PrevAvailable; - if (not regex_search(m_next_begin, m_end, m_results, *m_regex, - m_flags | additional_flags)) - m_regex = nullptr; + if (direction == MatchDirection::Forward) + { + if (m_begin != m_next_pos) + additional_flags |= RegexExecFlags::NotBeginOfSubject | RegexExecFlags::PrevAvailable; + + if (not regex_search(m_next_pos, m_end, m_results, *m_regex, + m_flags | additional_flags)) + m_regex = nullptr; + else + m_next_pos = m_results[0].second; + } else - m_next_begin = m_results[0].second; + { + if (not regex_search(m_begin, m_next_pos, m_results, *m_regex, + m_flags | additional_flags)) + m_regex = nullptr; + else + m_next_pos = m_results[0].first; + } } const Regex* m_regex = nullptr; MatchResults m_results; - Iterator m_next_begin{}; + Iterator m_next_pos{}; const Iterator m_begin{}; const Iterator m_end{}; const RegexExecFlags m_flags = RegexExecFlags::None;