токенизация строк в C ++, включая символы-разделители - PullRequest
4 голосов
/ 22 марта 2012

У меня есть строки следующего вида a = x + y или abc = xyz + 5 или 6 + 5 или f(p)

Мне нужно, чтобы токенизация строки была такой, чтобы я читал каждый operator и operandпоэтому для a = x + y возврат токенов должен составлять a,=,x,+,y, а в случае abc=xyz+5 он должен возвращать abc,=,xyz,+,5.обратите внимание, что между operator и operands

может быть или не быть пробелов, это то, что я пробовал

void tokenize(std::vector<std::string>& tokens, const char* input, const char* delimiters) {
    const char* s = input;
    const char* e = s;
    while (*e != 0) {
        e = s;
        while (*e != 0 && strchr(delimiters, *e) == 0) {
            ++e;
        }
        if ( *e != ' ' && strchr(delimiters, *e) != 0 ){
            std::string op = "";
            op += *e;
            tokens.push_back(op);
        }
        if (e - s > 0) {
            tokens.push_back(std::string(s,e - s));
        }
        s = e + 1;
    }
}

Ответы [ 2 ]

5 голосов
/ 22 марта 2012

Вы можете использовать эту реализацию.Первый аргумент - это std :: string, который вы хотите маркировать, второй аргумент - это разделитель, который вы хотите использовать.Возвращает вектор строк с токенами.Очень просто, но эффективно.

vector<string> tokenizeString(const string& str, const string& delimiters)
{  
   vector<string> tokens;
   // Skip delimiters at beginning.
   string::size_type lastPos = str.find_first_not_of(delimiters, 0);
   // Find first "non-delimiter".
   string::size_type pos = str.find_first_of(delimiters, lastPos);

   while (string::npos != pos || string::npos != lastPos)
    {  // Found a token, add it to the vector.
      tokens.push_back(str.substr(lastPos, pos - lastPos));
      // Skip delimiters.  Note the "not_of"
      lastPos = str.find_first_not_of(delimiters, pos);
      // Find next "non-delimiter"
      pos = str.find_first_of(delimiters, lastPos);
   }
    return tokens;
}
4 голосов
/ 22 марта 2012

В этом примере используется токенайзер boost для достижения желаемого поведения:

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

using namespace std;
using namespace boost;

int main(int , char* [])
{
    const string formula = " ABC + BYZ =6 +5";

    typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
    boost::char_separator<char> sep(" ", "+-=");

    tokenizer tokens(formula, sep);

    for (tokenizer::iterator tok_iter = tokens.begin();tok_iter != tokens.end(); ++tok_iter)
        std::cout << "<" << *tok_iter << "> ";

    return 0;
}

Выход

<+> <=> <6> <+> <5>

Пробелы пропущены, разделители включены

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...