首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C++ 解析 vCard:其實就是文本解析,正則表達式或手寫狀態機即可,無需專用庫

     編輯:程式設計綜合問答

vCard (`.vcf`) 本質是結構化文本,格式規範見 RFC 6350。C++ 無成熟專用庫,但自己寫解析器極簡單。

vCard 結構示例

BEGIN:VCARD
VERSION:3.0
N:Zhang;San;;;
FN:Zhang San
TEL;TYPE=CELL:+86 138 0000 1111
EMAIL:zhangsan@example.com
END:VCARD

方案一:正則表達式(C++17 ``)

std::string readFile(const std::string& path) { /* 讀全文 */ }
std::vector parseVCard(const std::string& content) {
    std::vector contacts;
    std::regex cardRegex("BEGIN:VCARD([\\s\\S]*?)END:VCARD");
    std::regex propRegex("([A-Z]+)(?:;([^:]*))?:(.*)");
    
    for (auto it = std::sregex_iterator(content.begin(), content.end(), cardRegex);
         it != std::sregex_iterator(); ++it) {
        Contact c;
        std::string card = (*it)[1];
        for (auto pit = std::sregex_iterator(card.begin(), card.end(), propRegex);
             pit != std::sregex_iterator(); ++pit) {
            std::string key = (*pit)[1];
            std::string params = (*pit)[2];
            std::string value = (*pit)[3];
            // 解析 key/params/value 填充 Contact 結構體
        }
        contacts.push_back(c);
    }
    return contacts;
}

方案二:手寫狀態機(性能更高、無 regex 開銷)

enum State { START, IN_CARD, IN_PROP };
State state = START;
Contact current;
for (char ch : content) {
    switch (state) {
        case START:
            if (ch == 'B') { /* 檢測 BEGIN:VCARD */ state = IN_CARD; }
            break;
        case IN_CARD:
            if (ch == 'E') { /* 檢測 END:VCARD */ contacts.push_back(current); current = {}; state = START; }
            else if (ch != '\r' && ch != '\n') { /* 解析屬性行 */ }
            break;
    }
}

現成參考

  • GitHub 搜 `vcf parser cpp` 有多個頭文件級實現。
  • Qt 專案可用 `QContactManager`(需 Mobility 模塊,較舊)。

**結論**:vCard 解析屬於「造輪子更快」的場景,正則幾十行搞定,無需引入重型依賴。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved