|
地板
樓主 |
發表于 2009-6-30 09:32:22
|
只看該作者
如果對正則表達式的機理有一定了解,就可以借助這個經驗猜到這個函數大概是把正則表達
式字符串轉換成狀態機以便高效地匹配目標字符串。如果以前用過其它編程語言的正則表達
式庫函數,也可以借助這些經驗知道正則表達式在使用之前大多有一個預處理的步驟。另
外,對英文縮寫要有一定敏感性,函數名是regcomp,reg就是正則表達式,comp是compare還
是compile?如果是compare,那應該有兩個相同類型的參數來做比較,就像strcmp,這里顯
然是compile,編譯,把字符串形式轉為二進制形式,從另一個側面也驗證了前面的猜測。這
些都是靠經驗而不是推理得到的,經驗有助于更快更準確地理解,但不是必須的,因為事實
上我們通過上面基于傳入傳出參數的推理已經猜出正確結論了,只不過有經驗的人會對自己
的猜測更自信。
對英文縮寫敏感是看man page和看代碼需要具備的最基本的能力,但這需要長期的練習才能
找到感覺。也許你要學會一個函數怎么用并不必知道函數名和各個參數名是什么的縮寫,你
通過以上列舉的兩本爛書就可以學會怎么用,但如果總是回避man page,總是不去做猜縮寫
的練習,就不可能看懂別人的代碼,不看別人的代碼就自己亂寫代碼,連變量名該怎么起都
不知道,寫出來的永遠是垃圾代碼。對于regcomp這個函數名以及各參數名,regex是
regular expression,regcomp是regular expression compile。那么preg是什么?reg是
regular expression,p表示什么呢?表示指針?那是微軟的infamous的hungarian
notation,Linux上肯定不是這么用的,這里的p我猜是precompiled。cflags的c是什么?不
知道,但是跟下面一個函數對比來看:
C代碼
1. int regexec(const regex_t *preg, const char *string, size_t nmatch,
2. regmatch_t pmatch[], int eflags);
int regexec(const regex_t *preg, const char *string, size_t nmatch,
regmatch_t pmatch[], int eflags);
這個函數有個參數叫eflags。所以c是regcomp的c,而e是regexec的e,一個是編譯時的
flags,一個是執行時的flags,這兩種flags的取值必然不同,下文必然會分別說明。這又是
一種猜測:猜測下文的行文邏輯。這種猜測同樣是非常有助于理解的。后面幾個函數的函數
名和參數名是怎么縮寫的,留給讀者自己練習。
preg參數在regcomp中是傳出參數,在regexec中卻是傳入參數,根據推理,preg是由
regcomp函數填寫好之后傳給regexec函數用的,也就是說正則表達式以轉換之后的二進制格
式傳給regexec函數來用。regexec又有一個字符串傳入參數string,還有兩個match參數表示
匹配結果,pmatch是傳出參數,表示緩沖區首地址,nmatch表示緩沖區長度(根據經驗,這
類似于strncpy),這必然就是我一開始想要的my_expect_func了:
C代碼
1. int my_expect_func(傳入:正則表達式, 傳入:目標字符串, 傳出:匹配結果);
2. 返回:錯誤碼
int my_expect_func(傳入:正則表達式, 傳入:目標字符串, 傳出:匹配結果);
返回:錯誤碼
preg對應正則表達式,pmatch和nmatch對應匹配結果,因此string這個傳入參數必然是目標
字符串了。pmatch是一個指針變量,但是寫成pmatch[],說明它指向的是一組而不是一個
regmatch_t類型的對象,這一組有多少個呢?用nmatch參數表示。和strncpy類似,這一組
regmatch_t對象應該由我們事先分配好再傳給函數。因此這兩個函數應該是這樣調用的:
C代碼
1. regex_t regobj;
2. regcomp(®obj, "正則表達式", 標志位1|標志位2|...);
3. regmatch_t matchbuf[10];
4. regexec(®obj, "目標字符串", 10, matchbuf, 標志位1|標志位2|...);
regex_t regobj;
regcomp(®obj, "正則表達式", 標志位1|標志位2|...);
regmatch_t matchbuf[10];
regexec(®obj, "目標字符串", 10, matchbuf, 標志位1|標志位2|...);
regmatch_t對象如何表示一個匹配呢?如果一個正則表達式模式在一個目標字符串中有五次
出現,如何表示這五次出現呢?可以猜測這個regmatch_t結構體一定包含了在目標字符串中
的匹配位置信息。另外,我傳進去10個regmatch_t對象,如果只有五次匹配,函數返回后我
怎么知道前面五個對象是有效的匹配信息而后面是無效的呢?是不是通過一個參數或返回值
表示匹配次數的?該函數并沒有額外的參數,而且快速翻看一下man page的RETURN
VALUE節,這個函數返回值是錯誤碼,也不表示匹配次數。那這個函數一定會在后面無效的
regmatch_t對象里填充一個特殊值,這就是推理,這個猜測將會在閱讀后面的文字時證實或
證偽,不管猜得對不對,一定會在后面得到答案。 |
|