Я стал здесь опаздывающим, но возвращающийся к исходному вопросу, почему не просто используют lookarounds?
Pattern p = Pattern.compile("(?<=\\w)(?=\\W)|(?<=\\W)(?=\\w)");
System.out.println(Arrays.toString(p.split("'ab','cd','eg'")));
System.out.println(Arrays.toString(p.split("boo:and:foo")));
вывод:
[', ab, ',', cd, ',', eg, ']
[boo, :, and, :, foo]
РЕДАКТИРОВАНИЕ: То, что Вы видите выше, - то, что появляется на командной строке, когда я выполняю тот код, но я теперь вижу, что это немного сбивает с толку. Трудно отслеживать, которых запятые являются частью результата и которые были добавлены Arrays.toString()
. Подсветка синтаксиса SO не помогает также. В надежде на то, чтобы заставлять выделение работать с меня вместо против меня, вот то, как те массивы посмотрели бы он, я объявлял их в исходном коде:
{ "'", "ab", "','", "cd", "','", "eg", "'" }
{ "boo", ":", "and", ":", "foo" }
я надеюсь, что это легче считать. Спасибо за предостережение, @finnw.
для каждого оператора
в VC ++ при использовании на неуправляемый класс:
for each (T x in xs)
{
...
}
просто синтаксический сахар для этого:
for (auto iter = xs.begin(), end = xs.end(); iter != end; ++iter)
{
T x = *iter;
}
Где auto
означает, что тип переменной выводится автоматически из типа инициализатора.
Другими словами, вам необходимо предоставить методы begin ()
и end ()
в вашем классе, которые будут возвращать для него итераторы ввода начала и конца.
Вот пример класса, который является оболочкой istream
и позволяет вам перебирать все строки в нем:
#include <istream>
#include <iostream>
#include <fstream>
#include <string>
class lines
{
public:
class line_iterator
{
public:
line_iterator() : in(0)
{
}
line_iterator(std::istream& in) : in(&in)
{
++*this;
}
line_iterator& operator++ ()
{
getline(*in, line);
return *this;
}
line_iterator operator++ (int)
{
line_iterator result = *this;
++*this;
return result;
}
const std::string& operator* () const
{
return line;
}
const std::string& operator-> () const
{
return line;
}
friend bool operator== (const line_iterator& lhs, const line_iterator& rhs)
{
return (lhs.in == rhs.in) ||
(lhs.in == 0 && rhs.in->eof()) ||
(rhs.in == 0 && lhs.in->eof());
}
friend bool operator!= (const line_iterator& lhs, const line_iterator& rhs)
{
return !(lhs == rhs);
}
private:
std::istream* const in;
std::string line;
};
lines(std::istream& in) : in(in)
{
}
line_iterator begin() const
{
return line_iterator(in);
}
line_iterator end() const
{
return line_iterator();
}
private:
std::istream& in;
};
int main()
{
std::ifstream f(__FILE__);
for each (std::string line in lines(f))
{
std::cout << line << std::endl;
}
}
Обратите внимание, что реализация line_iterator
на самом деле несколько больше минимума, необходимого для для каждой
; однако это минимальная реализация, которая соответствует требованиям итератора ввода, и, следовательно, этот класс также можно использовать со всеми алгоритмами STL, которые работают с итераторами ввода, такими как std :: for_each
, std :: найдите
и т. д.
#include <istream>
#include <iostream>
#include <fstream>
#include <string>
class lines
{
public:
class line_iterator
{
public:
line_iterator() : in(0)
{
}
line_iterator(std::istream& in) : in(&in)
{
++*this;
}
line_iterator& operator++ ()
{
getline(*in, line);
return *this;
}
line_iterator operator++ (int)
{
line_iterator result = *this;
++*this;
return result;
}
const std::string& operator* () const
{
return line;
}
const std::string& operator-> () const
{
return line;
}
friend bool operator== (const line_iterator& lhs, const line_iterator& rhs)
{
return (lhs.in == rhs.in) ||
(lhs.in == 0 && rhs.in->eof()) ||
(rhs.in == 0 && lhs.in->eof());
}
friend bool operator!= (const line_iterator& lhs, const line_iterator& rhs)
{
return !(lhs == rhs);
}
private:
std::istream* const in;
std::string line;
};
lines(std::istream& in) : in(in)
{
}
line_iterator begin() const
{
return line_iterator(in);
}
line_iterator end() const
{
return line_iterator();
}
private:
std::istream& in;
};
int main()
{
std::ifstream f(__FILE__);
for each (std::string line in lines(f))
{
std::cout << line << std::endl;
}
}
Обратите внимание, что реализация line_iterator
на самом деле несколько больше, чем минимум, необходимый для для каждого
; однако это минимальная реализация, которая соответствует требованиям итератора ввода, и, следовательно, этот класс также можно использовать со всеми алгоритмами STL, которые работают с итераторами ввода, такими как std :: for_each
, std :: найдите
и т. д.
#include <istream>
#include <iostream>
#include <fstream>
#include <string>
class lines
{
public:
class line_iterator
{
public:
line_iterator() : in(0)
{
}
line_iterator(std::istream& in) : in(&in)
{
++*this;
}
line_iterator& operator++ ()
{
getline(*in, line);
return *this;
}
line_iterator operator++ (int)
{
line_iterator result = *this;
++*this;
return result;
}
const std::string& operator* () const
{
return line;
}
const std::string& operator-> () const
{
return line;
}
friend bool operator== (const line_iterator& lhs, const line_iterator& rhs)
{
return (lhs.in == rhs.in) ||
(lhs.in == 0 && rhs.in->eof()) ||
(rhs.in == 0 && lhs.in->eof());
}
friend bool operator!= (const line_iterator& lhs, const line_iterator& rhs)
{
return !(lhs == rhs);
}
private:
std::istream* const in;
std::string line;
};
lines(std::istream& in) : in(in)
{
}
line_iterator begin() const
{
return line_iterator(in);
}
line_iterator end() const
{
return line_iterator();
}
private:
std::istream& in;
};
int main()
{
std::ifstream f(__FILE__);
for each (std::string line in lines(f))
{
std::cout << line << std::endl;
}
}
Обратите внимание, что реализация line_iterator
на самом деле несколько больше, чем минимум, необходимый для для каждого
; однако это минимальная реализация, которая соответствует требованиям итератора ввода, и, следовательно, этот класс также можно использовать со всеми алгоритмами STL, которые работают с итераторами ввода, такими как std :: for_each
, std :: найдите
и т. д.
Ваш класс должен унаследовать IEnumerable для использования foreach
Насколько мне известно, foreach не является частью языка C ++. Хотя это на C #. Кроме того, я думаю, что STL и / или Boost имеют метод foreach. Возможно, вы думаете об этом?