C++11 では、 regex_token_iteratorを使用して、エスケープされたコンマも非常に簡単に処理できます。
std::stringstream ss(sText);
std::string item;
const regex re{"((?:[^\\\\,]|\\\\.)*?)(?:,|$)"};
std::getline(ss, item)
m_vecFields.insert(m_vecFields.end(), sregex_token_iterator(item.begin(), item.end(), re, 1), sregex_token_iterator());
vector<string>
ちなみに、次のように CSV から単純に を作成したい場合は、次のstring
ようにしitem
ます。
const regex re{"((?:[^\\\\,]|\\\\.)*?)(?:,|$)"};
vector<string> m_vecFields{sregex_token_iterator(item.begin(), item.end(), re, 1), sregex_token_iterator()};
【実例】
の簡単な説明regex
がおそらく適切です。(?:[^\\\\,]|\\\\.)
エスケープ文字または非','
文字に一致します。(詳細については、こちらを参照してください: https://stackoverflow.com/a/7902016/2642059 )*?
貪欲な一致ではないことを意味するため、最初 ','
に到達したところで停止します。キャプチャにネストされているものはすべて、最後のパラメーターである1
, toによって選択されますregex_token_iterator
。最後に、 -delimiter または . の末尾に(?:,|$)
一致します。','
string
この標準の CSV リーダーが空の要素を無視するようにするには、複数の文字を含む文字列のみに一致するように正規表現を変更できます。
const regex re{"((?:[^\\\\,]|\\\\.)+?)(?:,|$)"};
1 つ以上の一致する文字が必要であることを示す'+'
が置き換えられたことに注意してください。これにより、で終わる文字列と'*'
一致しなくなります。この例をここで見ることができます: http://ideone.com/W4n44Witem
','