boost 字串處理

2021-06-27 20:32:35 字數 3418 閱讀 9481

**:

c++在stl庫中提供了乙個string類用以代替c語言的char*來實現字串功能,不過stl的string只提供了乙個連線字串和查詢的功能,其它的常用函式幾乎一律沒有,就連字串替換都得自己來實現,和c#的字串函式比起來簡直弱爆了。

boost庫在標頭檔案中提供了不少字串處理函式,用以幫助我們實現基本的字串處理功能,極大程度上緩解了字串函式不夠用的問題。命名空間:boost::algorithm;

stringstr1("hello abc-*-abc-*-abc goodbye");

vector splitvec; // #2: search for tokens

split(splitvec, str1, is_any_of("-*"), token_compress_on); // splitvec ==

上述**就提供了乙個split的功能,不過和c#的版本相比,還是不夠簡潔,如果設計成這樣就更加好用了:

autosplitvec = split(str1, is_any_of("-*"), token_compress_on);

之所以不以這種形式設計,貌似是因為如果在split函式裡構造返回值的話,會有一次資料拷貝的開銷。從中也可以看出,boost的設計還是以效能為主的。而.net程式天然沒有返回值拷貝帶來的開銷,可以採取那種更簡潔的介面形式。

ps:我覺得可以像.net那樣,在堆變數中儲存結果,然後通過auto_ptr封裝後作作為返回值。即有簡潔的介面形式,又沒有資料拷貝的開銷,堆變數也能通過auto_ptr自動釋放。

同樣,也是出於效能方向的考慮,對於會產生新字串的函式,往往會有乙個***和***_copy兩個版本,例如tolower就有to_lower和to_lower_copy兩個版本:乙個是直接變更本身的值,乙個是構造新字串,具體選取那個根據實際場景來考慮。

另外,字串比較函式中,往往有區分大小寫和不區分大小寫的演算法。在boost中並不是通過引數來控制,而是直接提供***和i***兩個版本,其中i就表示ignor case。如equals和iequals。還有的需要和條件函式一併使用的,這時就會提供乙個***_if的版本。

由於提供的字串函式比較多,這裡我只按每類列舉幾個常用的函式和示例,如果同乙個演算法有***_copy的版本或i***版本,也只列舉基本的形式。其它的情參看boost文件。

case conversion

大小寫轉換涉及到四個函式:to_upper()、to_upper()以及***_copy的版本。基本用法如下:

cout << to_upper_copy(string("hello world")) << endl;

trimming

trimming函式主要有trim()、trim_left()、trim_right()和他們的***_copy和***_if版本。用於去除字串首位的空白字元:

cout << trim_copy(std::string(" hello world")) << endl;

當然,也不限於只去掉空白字元:

cout << trim_copy_if(std::string(",,,hello world"), is_any_of(" ,.:")) << endl;

predicates

predicates函式主要有:starts_with() 、ends_with() 、contains() 、equals() 、lexicographical_compare() 、all()以及他們的i***版本。基本上從名字裡就可以看出怎麼用了:

cout << (ends_with("hello world", "world") ? "true": "false") << endl;

find algorithms

查詢演算法有好幾種:find()、first()、find_last()、find_nth() 、find_head()、find_tail()、find_token()、find_regex()。常見的用法如下:

autoresult = find_first("hello world", "world");

if(result.empty())

cout << "can't find result"<< endl;

else

cout << result << endl;

其中result是乙個boost::iterator_range型別的物件,可以用它來構造子串。

strings("hello world");

cout << s.substr(find_first(s, "wo").begin() - s.begin()) <

或者來個更複雜點的:

stringstr1("abc-*-abc-*-abc");

for(autoit = make_find_iterator(str1, first_finder("abc", is_iequal())); !it.eof(); ++it)

erase/replace

boost把erase和replace函式分開來列了,這樣的好處是命名比較清晰,但不好的地方時函式變得非常多,不如過載的形式那麼好記。

replace的函式有replace_all() 、replace_first()、 replace_last() 以及它們的變體,加上erase,共有20多種,這裡就不一一枚舉了。

cout << replace_all_copy(string("hello world"), "l", "-") << endl;

split

split函式的用法前面以及介紹過:

stringstr1("hello abc-*-abc-*-abc goodbye");

vector splitvec;

split(splitvec, str1, is_any_of("-*"), 

token_compress_on

);需要注意的是這裡的token_compress_on引數,它可以吧連續多個分隔符當乙個,預設沒有開啟,當用的時候一般是要開啟的。

另外,boost把find_all函式也分到split一類裡面去了,它們的用法到也確實類似。);;

findvec;

ifind_all( findvec, str1,  );

join

join函式則是和split相反,用於把多個字串拼接起來。

std::array k = ;

cout << join(k, "-");        //

輸出結果為:

hello-world-123

它要求先把引數放到容器裡,不像.net的那樣可以直接傳入動態引數那樣好用,如果能寫成這樣的過載形式會更好點(當然,自己封乙個也不難):

join("-", "hello", "world", "123", …) 其它

其它還有一些條件函式,主要配合演算法使用。如前面已經見過的is_any_of()、常用的還有is_upper()、is_lower()、is_digit()、is_space()等,這裡就不多介紹了。

優秀的boost字串處理

我將把我認為非常有用,c 標準庫又不是特別完備的做下重新學習做下筆記 字串處理,檔案系統等 在c 03中字串的處理相當不靈活 對比mfc的cstring的實現,我們可以發現string不僅缺少了分詞的tokenizer,替換字串的replace也沒有實現根據輸入子串的替換,不僅沒有format還缺少...

(三)Boost庫之字串處理

字串處理一直是c c 的弱項,string algo庫很好的彌補了這一點。string algo 庫演算法命名規則 字首i 有這個字首表名演算法的大小寫不敏感,否則大小寫敏感 字尾 copy 有這個字尾表明演算法不變動輸入,返回處理結果的拷貝,否則演算法原地處理 字尾 if 有這個字尾表明演算法需要...

boost 字串模組

1.boost algorithm earse all copy 用來刪除所有字串中所有匹配字元 boost algorithm earse all copy int main 2.boost algorithm erase first copy 刪除第乙個 boost algorithm eras...