C++ (Qt)#include <iostream>#include <boost/regex.hpp>#include <string>#include <list>#include <boost/range/istream_range.hpp>#include <algorithm> template <class T = char>class tex_string_iterator : public std::iterator<std::bidirectional_iterator_tag, T, ptrdiff_t, const T*, const T&>{public: typedef T char_type; typedef std::basic_string<T> string_type; typedef typename std::basic_string<T>::const_iterator string_iterator; tex_string_iterator(string_iterator begin, string_iterator end, T bra = '%', T ket = '\n') : _begin(begin), _end(end), _it(begin), _bra(bra), _ket(ket) { make_comments_list(); } tex_string_iterator(const tex_string_iterator<T>& iter) : _begin(iter._begin), _end(iter._end), _it(iter._it), _bra(iter._bra), _ket(iter._ket), _comments_list(iter._comments_list) {} tex_string_iterator<T>& operator=(const tex_string_iterator & iter) { if (this != &iter) { _begin = iter._begin; _end = iter._end; _it = iter._it; _bra = iter._bra; _ket = iter._ket; _comments_list = iter._comments_list; } return *this; } tex_string_iterator() {} ~tex_string_iterator() {} const T& operator*() const { return *_it; } const T* operator->() const { return _it; } tex_string_iterator<T>& operator++() { if (*_it != _bra) { if (++_it == _end) return *this; if (*_it != _bra) return *this; } for (const auto & comment : _comments_list) { if (comment.begin() == _it) { _it = comment.end(); if (_it == _end) break; if (*(++_it) != _bra) break; } } return *this; } tex_string_iterator<T> operator++(int) { tex_string_iterator<T> tmp = *this; ++*this; return tmp; } tex_string_iterator<T>& operator--() { if (*_it != _ket) { --_it; if (*_it != _ket) return *this; } for (const auto & comment :_comments_list) { if (comment.end() == _it) { _it = comment.begin(); if (_it == _begin) break; if (*(--_it) != _ket) break; } } return *this; } tex_string_iterator<T> operator--(int) { tex_string_iterator<T> tmp = *this; --*this; return tmp; } template <class R> friend bool operator==(const tex_string_iterator<R> &, const tex_string_iterator<R> &); template <class R> friend bool operator!=(const tex_string_iterator<R> &, const tex_string_iterator<R> &); private: string_iterator _begin; string_iterator _end; string_iterator _it; //current iterator T _bra; //open comment symbol T _ket; //closed comment symbol std::list<boost::iterator_range<string_iterator>> _comments_list; void make_comments_list() { if (_begin == _end) return; auto first = _begin; auto second = _begin; while ((first = std::find(first, _end, _bra)) != _end) { second = std::find(first, _end, _ket); _comments_list.push_back(boost::iterator_range<string_iterator>(first, second)); first = second; } }}; template<class T>inline bool operator==(const tex_string_iterator<T> & x, const tex_string_iterator<T> & y) { return (x._it == y._it);} template<class T>inline bool operator!=(const tex_string_iterator<T> & x, const tex_string_iterator<T> & y) { return !(x == y);} int main(){ std::string buffer = "text text %comment comment\n text nocomment"; tex_string_iterator<char> ibegin(buffer.begin(), buffer.end(), '%', '\n'); tex_string_iterator<char> iend(buffer.end(), buffer.end()); boost::regex_iterator<tex_string_iterator<char>> it(ibegin, iend, boost::regex("(com)")); boost::regex_iterator<tex_string_iterator<char>> end; for (; it != end; ++it) { std::cout << it->str(1) << std::endl; } return 0;}
C++ (Qt)#include <string>#include <list>#include <boost/regex.hpp>#include <boost/range/istream_range.hpp>#include <algorithm> template <class T = char>class tex_string_iterator : public std::iterator<std::bidirectional_iterator_tag, T, ptrdiff_t, const T*, const T&>{public: typedef T char_type; typedef std::basic_string<T> string_type; typedef typename std::basic_string<T>::const_iterator string_iterator; typedef boost::regex regex_type; tex_string_iterator(string_iterator begin, string_iterator end, const regex_type & comment) : _begin(begin), _end(end), _it(begin), _comment(comment) { make_comments_list(); } tex_string_iterator(const tex_string_iterator<T>& iter) : _begin(iter._begin), _end(iter._end), _it(iter._it), _comment(iter._comment), _comments_list(iter._comments_list) {} tex_string_iterator<T>& operator=(const tex_string_iterator & iter) { if (this != &iter) { _begin = iter._begin; _end = iter._end; _it = iter._it; _comment = iter._comment; _comments_list = iter._comments_list; } return *this; } tex_string_iterator() {} ~tex_string_iterator() {} const T& operator*() const { return *_it; } const T* operator->() const { return _it; } tex_string_iterator<T>& operator++() { auto cur = _it; ++_it; for (const auto & comment : _comments_list) { if ((comment.begin() == _it) || (comment.begin() == cur)) { _it = comment.end(); if (_it == _end) break; ++_it; } } return *this; } tex_string_iterator<T> operator++(int) { tex_string_iterator<T> tmp = *this; ++*this; return tmp; } tex_string_iterator<T>& operator--() { auto cur = _it; --_it; for (const auto & comment : _comments_list) { if ((comment.end() == _it) || (comment.end() == cur)) { _it = comment.begin(); if (_it == _begin) break; --_it; } } return *this; } tex_string_iterator<T> operator--(int) { tex_string_iterator<T> tmp = *this; --*this; return tmp; } template <class R> friend bool operator==(const tex_string_iterator<R> &, const tex_string_iterator<R> &); template <class R> friend bool operator!=(const tex_string_iterator<R> &, const tex_string_iterator<R> &); private: string_iterator _begin; string_iterator _end; string_iterator _it; //current iterator regex_type _comment; std::list<boost::iterator_range<string_iterator>> _comments_list; void make_comments_list() { if (_begin == _end) return; auto first = _begin; boost::match_results<string_iterator> what; while (boost::regex_search(first, _end, what, _comment)) { _comments_list.push_back(boost::iterator_range<string_iterator>(what[1].first, what[1].second)); first = what[1].second; } }}; template<class T>inline bool operator==(const tex_string_iterator<T> & x, const tex_string_iterator<T> & y) { return (x._it == y._it);} template<class T>inline bool operator!=(const tex_string_iterator<T> & x, const tex_string_iterator<T> & y) { return !(x == y);} int main(){ boost::regex expr("([#\\\\][^\\n]*)"); std::string buffer = "text#comment\ntext\\comment "; tex_string_iterator<char> iter(buffer.begin(), buffer.end(), expr); tex_string_iterator<char> end(buffer.end(), buffer.end(), expr); for (; iter != end; ++iter) { std::cout << *iter; } return 0;}