設置BCB6 Project屬性的Lib Path和Include Path為你安裝boost的目錄,運行你會看到結果:
index.html
可以看到index.html已經從字符串中提出出來了,那么為什么會是這樣呢?
代碼的核心部分是:
regex expression("\\s+href\\s*=\\s*\"([^\"]*)\"",regbase::normal|regbase::icase);
它用來設置如何匹配字符串,上面亂七八糟的字符串很難看懂,如果不了解正則表達式的書寫規則,上
面代碼可以和天書媲美。
regbase::normal|regbase::icase 是解析參數設置,具體可以參考boost幫助文檔。
正則表達式的書寫規則
具體的書寫規則,大家可以參看boost的文檔,我這里做一下簡要說明:
. (dot)
用來匹配任何一個字符,但不包括新行上的字符
*
閉包,任意有限次的自重復連接
+
有限次自重復連接,但至少出現一次
{}
指定可能的重復次數
例如:
ba* 匹配 b ba baa baaa等
ba+ 匹配 ba baa baaaaaaaaa等
ba{1,5} 匹配 ba baa baaa baaaa baaaaa
\
轉義字符,有很多用途,根據參數設置而變化,最常見的就是類似于c語言\的用法
\s
匹配空格
\w
匹配一個單詞
\d
匹配數字
()
有兩種用法:
1是合并的作用,例如(ab)*匹配ab abab ababab等
2是確定匹配,也就是說在()中的字符將被最終拆解出來
根據上面這張表,我們可以很容易知道前面的那段天書如何解釋。
一個實際的例子
前一段時間在CSDN上有一篇帖子,問題是有一種文件結構如(類似):
@People{
Age=19
Speek=”Hay,{name},how are you”
}
問如何拆分字符串得到@后面的名字,=兩邊的屬性名和屬性值,引號里{}種的名字。
解決這個問題用正則表達式再合適不過了。
根據分析,我們可以這樣構造匹配規則:
"@(.*?)\s*\\{" 匹配@開始的字符創,后面兩種類型如何構造匹配規則留給大家思考吧。
這樣我們可以輕易拆解這個例子。
性能分析
通過上面的討論,大家已經了解到boost的強大威力,那個性能又如何呢?為此我們再實際來拆分一個
復雜的html代碼,看看到底需要花費多少時間。
為了節省篇幅,這里就不列出html代碼了,不過可以告訴大家,這是一個又Word生成的大小為186K
的html文件,這個文件中用到了很多<table>標簽,所以我這里測試就來拆分所有<table>標簽的
width屬性。測試代碼如下:
#include<deque>
#include<iostream>
#include<algorithm>
#include<boost/regex.hpp>
#include<vcl.h>
int main()
{
using namespace boost;
using namespace std;
TStringList* html=new TStringList();
html->LoadFromFile("D:\\1.htm");
regex expression("\\s+width=([^\"]*)\s+",regbase::normal|regbase::icase);
DWORD start=GetTickCount();
for(int n=0;n<html->Count;n++)
{
string s=html->Strings[n].c_str();
deque<string> result;
regex_split(std::back_inserter(result),s,expression);
copy(result.begin(),result.end(),ostream_iterator<string>(cout,"\n"));
result.clear();
}
start=GetTickCount()-start;
delete html;
cout<<start;
int c;
cin>>c;
return 0;
}
輸出結果為671毫秒,拆分得到1072個width屬性值,我們可以看到boost的效率是非常高的,雖然與一些角本語言比起來解析速度還是慢,但已經可以滿足大多數編程要求了。另外作者的計算機配置并不是非常高,相信拿到現在任何一臺主流配置的計算機上都會優于作者的結果。
結束語
其實上面的強大威力只是boost的冰山一角,如果你不自己去體會,你很難想象到boost的強大威力。在boost里還有很多使用的庫,比如格式化輸出,字符串拆解,類型轉換等,這些庫使用起來也比較方便,大家可以自行參考boost文檔。在這些庫中還有兩個庫需要自行編譯,他們是Python和thread庫,而且這些庫的編譯需要專門的工具Jam,所以我們在編譯這些庫的時候還要編譯jam工具,而編譯jam工具也不是一件快樂的事情,麻煩同樣出現在如果你安裝了多個編譯器,如果讀者有興趣可以自己試一下。
不過BCB6并不支持全部boost庫,從boost提供的編譯器支持表可以看到[2],BCB6還是有相當多的庫不支持的,支持最好的是gcc/g++的編譯器,但也不是全部支持。希望borland下一個將要發布的C++編譯器可以支持更多C++標準。
[1] 其實還有其他類型的包,但在windows系統下,你最好下載zip包
[2] Boost提供的編譯器支持表是針對BCB5的,對于BCB6的支持作者并沒有詳細測試,如果讀者有興趣可以自己測試boost附帶的測試代碼。