2

次のような文字列があります。

"\r color=\"red\" name=\"Jon\" \t\n depth=\"8.26\""

std::listそして、この文字列を解析して、このオブジェクトのを作成したいと思います:

class data
{
    std::string name;
    std::string value;
};

たとえば、次のようになります。

name = color
value = red

最速の方法は何ですか?ブースト使えます。

編集:

これは私が試したことです:

vector<string> tokens;
split(tokens, str, is_any_of(" \t\f\v\n\r"));

if(tokens.size() > 1)
{
    list<data> attr;
    for_each(tokens.begin(), tokens.end(), [&attr](const string& token)
        {
            if(token.empty() || !contains(token, "="))
                return;

            vector<string> tokens;
            split(tokens, token, is_any_of("="));
            erase_all(tokens[1], "\"");
            attr.push_back(data(tokens[0], tokens[1]));
        }
    );
}

" "ただし、 : likeの中にスペースがある場合は機能しませんcolor="red 1"

4

2 に答える 2

1

の前に常に少なくとも 1 つの空白があると仮定するnameと、次のアルゴリズムは十分に高速だと思います。

list<data> l;
size_t fn, fv, lv = 0;

while((fv = str.find("\"", ++lv)) != string::npos &&
    (lv = str.find("\"", fv+1)) != string::npos)
{
    fn = str.find_last_of(" \t\n\v\f\r", fv);
    l.push_back(data(str.substr(++fn, fv-fn-2), str.substr(++fv, lv-fv)));
}

strあなたはどこstd::stringdataいて、このタイプのコンストラクターがあります:

data(string name, string value)
    : name(name), value(value)
{   }

ご覧のとおり、boost や regex を使用する必要はなく、単純に標準ライブラリを使用しました。

于 2012-07-03T17:47:49.030 に答える
0

編集後:スペースの問題に対して次のことを行うことができます。

(""引用符内にないすべてのスペースを\nに置き換えます)

void PrepareForTokanization(std::string &str)
{
    int quoteCount = 0;
    int strLen = str.length();
    for(int i=0; i<strLen; ++i){
        if (str[i] == '"' && (i==0 || (str[i-1] != '\\')))
            quoteCount++;
        if(str[i] == ' ' && quoteCount%2 == 0)
            str[i] = '\n';
    }
}

splitを呼び出す前に、文字列を準備してから、splitis_​​any_ofからスペース文字を削除します。

PrepareForTokanization(str);
split(tokens, str, is_any_of("\t\f\v\n\r"));
于 2012-07-02T21:33:32.180 に答える