C ++ токенизирует строку с помощью регулярного выражения - PullRequest
11 голосов
/ 14 июня 2009

Я сейчас пытаюсь научиться немного C ++ с нуля.
Я хорошо разбираюсь в Python, Perl, Javascript, но только кратко столкнулся с C ++, в обстановка в классе в прошлом. Прошу прощения за наивность моего вопроса.

Я хотел бы разбить строку, используя регулярное выражение, но мне не повезло четкий, точный, эффективный и полный пример того, как сделать это в C ++.

В Perl это обычное действие, и поэтому оно может быть выполнено тривиальным образом,

/home/me$ cat test.txt
this is  aXstringYwith, some problems
and anotherXY line with   similar issues

/home/me$ cat test.txt | perl -e'
> while(<>){
>   my @toks = split(/[\sXY,]+/);
>   print join(" ",@toks)."\n";
> }'
this is a string with some problems
and another line with similar issues

Я хотел бы знать, как лучше всего выполнить эквивалент в C ++.

EDIT:
Я думаю, что нашел то, что искал в библиотеке наддува, как упомянуто ниже.

boost regex-token-iterator (почему не подчеркивается работа?)

Наверное, я не знал, что искать.


#include <iostream>
#include <boost/regex.hpp>

using namespace std;

int main(int argc)
{
  string s;
  do{
    if(argc == 1)
      {
        cout << "Enter text to split (or \"quit\" to exit): ";
        getline(cin, s);
        if(s == "quit") break;
      }
    else
      s = "This is a string of tokens";

    boost::regex re("\\s+");
    boost::sregex_token_iterator i(s.begin(), s.end(), re, -1);
    boost::sregex_token_iterator j;

    unsigned count = 0;
    while(i != j)
      {
        cout << *i++ << endl;
        count++;
      }
    cout << "There were " << count << " tokens found." << endl;

  }while(argc == 1);
  return 0;
}

Ответы [ 5 ]

16 голосов
/ 14 июня 2009

Библиотеки повышения обычно являются хорошим выбором, в данном случае Boost.Regex . Существует даже пример для разбиения строки на токены, которые уже делают то, что вы хотите. По сути, все сводится к следующему:

boost::regex re("[\\sXY]+");
std::string s;

while (std::getline(std::cin, s)) {
  boost::sregex_token_iterator i(s.begin(), s.end(), re, -1);
  boost::sregex_token_iterator j;
  while (i != j) {
     std::cout << *i++ << " ";
  }
  std::cout << std::endl;
}
3 голосов
/ 14 июня 2009

Проверьте Boost.Regex. Я думаю, что вы можете найти свой ответ здесь:

C ++: какую библиотеку регулярных выражений мне следует использовать?

2 голосов
/ 14 июня 2009

Если вы хотите минимизировать использование итераторов и конкретизировать код, должно работать следующее:

#include <string>
#include <iostream>
#include <boost/regex.hpp>

int main()
{
  const boost::regex re("[\\sXY,]+");

  for (std::string s; std::getline(std::cin, s); ) 
  {
    std::cout << regex_replace(s, re, " ") << std::endl;   
  }

}
1 голос
/ 14 июня 2009

Regex являются частью TR1, включенного в Visual C ++ 2008 SP1 (включая экспресс-издание) и G ++ 4.3.

Заголовок <regex> и пространство имен std :: tr1. Отлично работает с STL.

Начало работы с регулярными выражениями C ++ TR1

Стандартная библиотека Visual C ++: регулярные выражения TR1

1 голос
/ 14 июня 2009

В отличие от Perl, регулярные выражения не «встроены» в C ++.

Вам необходимо использовать внешнюю библиотеку, такую ​​как PCRE .

...