處理電話號碼、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 構造函數,保留連續分隔符產生的空串 |
// 示例:按正則表達式分割 (需 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("[;,;,]")));
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(); });
// 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_s | C 標準庫、無依賴 | 破壞原串、非線程安全、不支持多字符分隔符 | 舊代碼維護、極簡環境 |
MFC CString::Tokenize | MFC 專案原生 | 僅支持單字符分隔符、修改原串 | 純 MFC 專案、簡單分割 |
std::vector StringUtil::Split(const std::string&, const std::string& delimiters, bool keepEmpty = false) 。<boost/tokenizer.hpp>,頭文件前向聲明減少編譯依賴。boost::char_separator<wchar_t> + std::wstring 處理寬字符。Boost.Tokenizer 以「策略模式」將分割邏輯與遍歷解耦,代碼既具備 STL 容器的標準感,又能靈活應對複雜分隔符場景。在現代 C++ 專案中,它是字符串分割的首選利器;若極度追求性能或去依賴,可參考 string_view 手寫實現,但維護成本將顯著上升。