2007年7月17日 星期二

在 VC IDE 的 Find/Replace 使用 Regular Expression

最近公司說要儘量把 compiler warnning 減到最少,在清理 warning 的過程中,我發現有一堆 warning 是來自像底下這種 code:

#define PI 3.14159
DSPfract p = PI;

會出現 warning C4305: 'initializing' : truncation from 'double' to 'float'.
原因是 DSPfract 會因不同的 #define 而被 typedef 成 float 或 double。當 DSPfract 被定為 float 時,warning 就會產生。這是因為 C++ 預設的小數型別是 double,當你把 double 的值傳給給 float 變數時,造成精準度降低,所以 compiler 就吐了一個 warning 出來。
先不談應該用 const variable 而不該用 #define PI 這種東西的問題,這個問題的關鍵是要讓 compiler 知道要以 float 來處理小數,像這樣:
#define PI 3.14159f

但這種地方很多,我可不想手動一個一個做,所以我打算直接在 Visual Studio IDE 中用 regular expression 來解決問題,regular expression 是我很不熟的東西,但做簡單的工作應該還不成問題。
先來看看該怎麼 find,小數就是一個連串的數字,後面緊接著一個小數點,然後再緊接著一連串的數字,所以我們寫 [0-9]+\.[0-9]+ 來尋找,果然還蠻順利的,但要記得勾選 match whole word。


尋找沒問題,接下來就是 replace 了。首先把 find 欄填的內容從 [0-9]+\.[0-9]+ 改成 ([0-9]+\.[0-9]+),用小刮號括起來表示這是一個 tag,等一下 replace 時會用到。接下來到 replace 欄位輸入 \1f,其中 \1 代表 find 的第一個 tag, 就是在 find 時 match 的字串。以此例來說,3.14159 就是我們的 tag 1,因此 \1f 就會被展開成為 3.14159f,這樣就可以達成目的了。
但當我一按 replace 時,3.14159 卻變成 f,而前面的數字不見了! 這是怎麼回事? 搞了半天才發現,原來在 VC 中 tag 要用大刮號,也就是要寫 {[0-9]+\.[0-9]+},而不是 ([0-9]+\.[0-9]+)!!


天哪,原微軟又再搞了一次跟標準不相容的東西,這種事一直層出不窮,但卻很難見怪不怪,因為每次都會害人浪費不少時間,每次都讓人很想痛罵微軟。
真搞不清楚把小刮號改成大刮號有什麼好玩的?

參考資料:
Visual Studio 的符號與標準 Regular Expression 符號的比較表。
MSDN 上關於 Visual Studio 裡的 Regular Expression 的說明。

沒有留言: