首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

Boost.Tokenizer 實現多格式分隔符字符串分割 (C++ 現代寫法)

     編輯:VC 教學

前言

處理電話號碼、CSV、日誌等文本時,常遇到多種分隔符混用 (半形/全形逗號、分號)。Boost.Tokenizer 以聲明式語法優雅解決此問題,本文展示完整實戰代碼。

一、分割需求分析

輸入字符串可能包含任意組合:

  • 半形分號 ;
  • 半形逗號 ,
  • 全形分號 ;
  • 全形逗號 ,

示例:"1391067,6617;62980;1234,5678;8989"

二、核心代碼

#include 
#include  // 可選:trim
#include 
#include 
#include 

void SplitMixedDelimiters(const std::string& input) {
    // 1. 定義分隔符集合 (字符級別)
    boost::char_separator sep(";,;,"); 

    // 2. 構建 tokenizer (保留空 token 需傳 boost::keep_empty_tokens)
    typedef boost::tokenizer> Tokenizer;
    Tokenizer tokens(input, sep);

    // 3. 遍歷輸出
    std::vector result;
    for (const auto& token : tokens) {
        // 可選:去除 token 兩端空白
        std::string trimmed = boost::algorithm::trim_copy(token);
        if (!trimmed.empty()) // 過濾空串
            result.push_back(trimmed);
    }

    // 4. 使用結果
    for (size_t i = 0; i < result.size(); ++i) {
        std::cout << "Token[" << i << "]: " << result[i] << std::endl;
    }
}

int main() {
    std::string s = "1391067,6617;62980;1234,5678;8989";
    SplitMixedDelimiters(s);
    return 0;
}

三、關鍵類解析

類/函數作用備註
boost::char_separator<Char>字符級分隔符定義構造函數接受分隔符字符串,每個字符獨立作為分隔符
boost::tokenizer<TokenizerFunc>分割迭代器範圍模板參數默認 char_separator,支持自定義分割邏輯
Tokenizer::iterator輸入迭代器解引用返回 std::string (或模板指定類型)
boost::keep_empty_tokens策略標籤傳給 tokenizer 構造函數,保留連續分隔符產生的空串

四、進階用法

1. 自定義分割邏輯 (如按正則、固定寬度)

// 示例:按正則表達式分割 (需 boost::regex)
#include 
#include 

struct RegexSeparator {
    RegexSeparator(const boost::regex& re) : _re(re) {}
    void operator()(const std::string& s, std::vector& tokens) const {
        boost::sregex_token_iterator it(s.begin(), s.end(), _re, -1), end;
        tokens.assign(it, end);
    }
    boost::regex _re;
};

// 使用
boost::tokenizer tok(str, RegexSeparator(boost::regex("[;,;,]")));

2. 直接輸出到容器 (C++11 範圍構造)

std::vector vec(tokens.begin(), tokens.end());
// 或配合算法
std::copy_if(tokens.begin(), tokens.end(), std::back_inserter(vec),
             [](const std::string& s) { return !s.empty(); });

3. 處理引號包裹字段 (CSV 模式)

// Boost 內置 escaped_list_separator 支持雙引號轉義
#include 
boost::escaped_list_separator els('\\', ',', '"'); // 轉義符、分隔符、引號
boost::tokenizer> csv_tok(csv_line, els);

五、性能與替代方案對比

方案優點缺點適用場景
Boost.Tokenizer標準庫風格、類型安全、支持自定義策略編譯慢、依賴 Boost 庫通用 C++ 專案、需高可維護性
C++17 std::string_view + 手寫循環零分配、極快、無依賴代碼冗長、易出錯高性能熱路徑、嵌入式/無 STL 環境
strtok/strtok_sC 標準庫、無依賴破壞原串、非線程安全、不支持多字符分隔符舊代碼維護、極簡環境
MFC CString::TokenizeMFC 專案原生僅支持單字符分隔符、修改原串純 MFC 專案、簡單分割

六、工程化建議

  1. 封裝通用工具函數:std::vector StringUtil::Split(const std::string&, const std::string& delimiters, bool keepEmpty = false)。
  2. 編譯優化:僅在需要的 cpp 包含 <boost/tokenizer.hpp>,頭文件前向聲明減少編譯依賴。
  3. Unicode 支持:使用 boost::char_separator<wchar_t> + std::wstring 處理寬字符。
  4. 單元測試:覆蓋連續分隔符、首尾分隔符、全形/半形混雜、空字符串、純分隔符串等邊界情況。

結語

Boost.Tokenizer 以「策略模式」將分割邏輯與遍歷解耦,代碼既具備 STL 容器的標準感,又能靈活應對複雜分隔符場景。在現代 C++ 專案中,它是字符串分割的首選利器;若極度追求性能或去依賴,可參考 string_view 手寫實現,但維護成本將顯著上升。

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