2

を使用して文字列をトークンに分割したいと思いBoost.Tokenizeます。引用符または括弧内のテキストは、単一のトークン全体である必要があります。具体的には、次のように行を分割する必要があります

"one (two),three" four (five "six".seven ) eight(nine, ten)

のようなトークンに

one (two),three
four
(five "six".seven )
eight
(nine, ten)

または多分

one (two),three
four
(
five "six".seven
)
eight
(
nine, ten
)

テキストを引用符でトークン化する方法は知っていますが、同時にテキストを括弧でトークン化する方法がわかりません。多分実装する必要がありますTokenizerFunction
私が説明したように文字列を分割する方法は?

4

1 に答える 1

1

TokenizerFunctionは2つのメソッドを持つファンクターであり、どちらも実装が非常に難しいはずではありません。1つはreset、ファンクターが持つ可能性のある状態をリセットすることを意味する、もう1つはoperator()、3つのパラメーターをとるです。最初の2つはイテレータであり、3つ目は結果のトークンです。

以下のアルゴリズムは単純です。まず、スペースをスキップします。最初の非スペース文字は3種類のうちの1つであると予想されます。引用符または左括弧の場合は、対応する終了区切り文字が見つかるまで検索し、見つかったものをトークンとして返します。引用符は削除されることになっていますが、括弧は残っているようです。最初の文字が別のものである場合は、次の区切り文字を検索して、代わりにそれを返します。

template <
  typename Iter = std::string::const_iterator,
  typename Type = std::string
  >
struct QuoteParenTokenizer
{
  void reset() { }

  bool operator()(Iter& next, Iter end, Type& tok) const
  {
    while (next != end && *next == ' ')
      ++next;
    if (next == end)
      return false; // nothing left to read

    switch (*next) {
      case '"': {
        ++next; // skip token start
        Item const quote = std::find(next, end, '"');
        if (quote == end)
          return false; // unterminated token
        tok.assign(next, quote);
        next = quote;
        ++next;
        break;
      }
      case '(': {
        Iter paren = std::find(next, end, ')');
        if (paren == end)
          return false; // unterminated token
        ++paren; // include the parenthesis
        tok.assign(next, paren);
        next = paren;
        break;
      }
      default: {
        Iter const first = next;
        while (next != end && *next != ' ' && *next != '"' && *next != '(')
          ++next;
        tok.assign(first, next);
      }
    }
    return true;
  }
};

としてインスタンス化しますtokenizer<QuoteParenTokenizer<> >。別のイテレータタイプまたは別のトークンタイプがある場合は、テンプレートパラメータでとの両方にそれらを示す必要がありtokenizer ます QuoteParenTokenizer

エスケープされた区切り文字を処理する必要がある場合は、より洗練されたものにすることができます。ネストするために括弧で囲まれた式が必要な場合は、作業が難しくなります。

現在のところ、上記のコードはテストされていないことに注意してください。

于 2012-02-21T20:25:33.483 に答える