Created
December 30, 2016 17:06
-
-
Save NicolBolas/f326fab93f237c2e1c2fb58b10442f18 to your computer and use it in GitHub Desktop.
C++ regex-based string splitter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
template<typename CharT, typename Traits = std::char_traits<CharT>> | |
class split_range_regex | |
{ | |
public: | |
using value_type = std::basic_string_view<CharT, Traits>; | |
using traits_type = Traits; | |
using size_type = typename value_type::size_type; | |
using difference_type = typename value_type::difference_type; | |
using reference = value_type; | |
using const_reference = reference; | |
using pointer = const value_type *; | |
using const_pointer = pointer; | |
using regex_type = std::basic_regex<CharT>; | |
class iterator : public std::forward_iterator_tag | |
{ | |
public: | |
iterator(value_type sv, const regex_type &re) | |
: it_(sv.begin(), sv.end(), re, -1) | |
{} | |
iterator() = default; | |
reference operator*() const {get_curr(); return curr_;} | |
pointer operator->() const {get_curr(); return &curr_;} | |
iterator &operator++() {++it_; return *this;} | |
iterator operator++(int) | |
{ | |
auto temp = *this; | |
++it_; | |
return temp; | |
} | |
bool operator==(const iterator &rhs) { return it_ == rhs.it_; } | |
bool operator!=(const iterator &rhs) { return it_ != rhs.it_; } | |
private: | |
using token_iterator = std::regex_token_iterator<typename value_type::iterator, CharT>; | |
token_iterator it_; | |
mutable value_type curr_; //Here just because -> requires a value to get a pointer to. | |
void get_curr() const | |
{ | |
auto match = *it_; | |
curr_ = value_type(&*match.first, match.length()); | |
} | |
}; | |
using const_iterator = iterator; | |
split_range_regex(value_type sv, const regex_type &re) | |
: first_(sv, re) | |
{} | |
split_range_regex() = delete; | |
iterator begin() const noexcept {return iterator(first_);} | |
const_iterator cbegin() const noexcept {return const_iterator(first_);} | |
iterator end() const noexcept {return iterator(past_last_);} | |
const_iterator cend() const noexcept {return const_iterator(past_last_);} | |
bool empty() const noexcept | |
{ | |
return past_last_ == first_; | |
} | |
private: | |
iterator first_; | |
iterator past_last_; | |
}; | |
template<typename CharT, typename Traits = std::char_traits<CharT>> | |
split_range_regex<CharT, Traits> split_string(std::basic_string_view<CharT, Traits> sv, | |
const typename split_range_regex<CharT, Traits>::regex_type &re) | |
{ | |
return split_range_regex<CharT, Traits>(sv, re); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment