2015-06-10 12 views
1

我想解析一個類似CSV的文件,行增加。 有喜歡的分裂,tokenise,精神,正則表達式許多不同的方法......CSV像解析(空白分隔符和提升)

一個解析線可能看起來像:"abc" "def" "hij \"hgfd\" " 和結果應該是這樣的:

"abc" 
"def" 
"hij \"hgfd\" " 

我認爲,使用升壓轉換器的tokenises與escaped_list_separator將是一個好主意,但它不可能分割空白分隔符,不是嗎?

+0

你有什麼? – sehe

+2

CSV(以及類似的文件格式)很容易被解析。我說的很迷惑,因爲有很多角落案例會引起問題,就像你注意到的那樣。爲了解決你的問題,你需要一個有狀態的解析器,你需要保持一個狀態,告訴你你解析的是什麼樣的標記。例如,如果狀態說你在一個字符串中,你應該讀空格並將它們添加到字符串中,而不是將它們作爲字段分隔符處理。 –

回答

1

這裏有一個快速和骯髒的你使用靈(多線成矢量>)描述的正是符合:

Live On Coliru

#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/qi_match.hpp> 
namespace qi = boost::spirit::qi; 

int main() { 
    std::vector<std::vector<std::string>> csv_data; 

    if (std::cin 
      >> std::noskipws 
      >> qi::phrase_match(*qi::lexeme['"' >> *('\\' >> qi::char_ | ~qi::char_("\r\n\"")) >> '"'] % qi::eol, qi::blank, csv_data)) 
    { 
     std::cout << "Parse succeeded: " << csv_data.size() << "\n"; 
     for(auto& row: csv_data) { 
      for(auto& c: row) std::cout << c << '|'; 
      std::cout << "\n"; 
     } 
    } else { 
     std::cout << "Parse failed\n"; 
    } 
} 

的例子打印:

Parse succeeded: 3 
abc|def|hij "hgfd" | 
qwehjr|aweqwejkl|| 

關於解析(任選地)引述分隔的字段,包括不同的引用字符('")的背景下,在這裏看到:

對於非常,非常,非常完整的例子以支持完成部分報價值和

splitInto(input, output, ' '); 

滿足HOD即採取 '任意' 輸出容器和分隔符表達式,在這裏看到:

+0

哇,真的很有表現力!優雅!靈活!驚人!你能寫一些關於這個例子中用來學習的技術嗎?即時通訊真的是新的這個c + +和提升。通常情況下,我將ansi c與一些C++(舊標準)混合在一起,是否有書? – Roby

+0

謝謝(我剛剛注意到我忘了將樣本直接複製到答案中) – sehe

+0

@Roby books:http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list - 有不是真正的增強書(但請參閱http://theboostcpplibraries.com/) – sehe