The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

如何利用 .NET 的 Regex 過濾所有特殊字元 (其他語言適用)

今天有個同事寫了一個小程式要將欄位中所有特殊字元過濾掉,他雖然用的是 規則運算式 (Regular Expression) 但寫法卻有瑕疵,我在 Code Review 的時候立即聞到這個程式碼的壞味道,很快的也用另一段更短的規則運算式 來解決這個小需求,而且也更加符合客戶的需要。

我先來分享今天看到用來判斷是否有特殊字元的規則運算式:

[^%!&+'"?<>/\\]+

從上述規則運算式就可以猜想的出他所寫的這些字元是憑印象寫出來的,不然就是看鍵盤上有哪些特殊字元才打上去的,可惜沒寫完整,連逗點、小數點、中刮號、大刮號、……都沒有加上。

為了解決這問題,我先從最核心的客戶需求著手進行思考,客戶的需求是要過濾「特殊字元」,但卻沒有定義何謂特殊字元特殊字元有哪些,況��客戶也不可能想的很全面,不過,需求發生的原因是因為該網站的資料需要透過 FTP 跟外部系統做交換,但是外部系統無法處理一些特殊字元,而導致資料交換失敗,所以才需要我們過濾「特殊字元」,不過要保留中文字或其他 Unicode 文字。

依照我個人的經驗,這種介接異常的系統通常都只會靠 ASCII 範圍的文字作為分隔符號,所以這些字元不太會超過 ASCII 0 ~ 127 的範圍,那麼這些特殊符號當然也就不可能超過這些字元範圍,如此以來,要判斷出有哪些字元是特殊符號就簡單多了,各位可以參考以下 ASCII 字元表:

ASCII Table

從上述的表格看來,很容易就可以判斷出哪些是你不要的字元,但是一一表列出來過濾似乎不太有效率,我有更好的方法。

首先,看看 規則運算式語言項目 - 字元類別\w 字元類別的定義相當於 [a-zA-Z_0-9] 這個規則運算式,另一個字元類別是 \W 字元類別 ( 大寫的 W ) 的定義相當於 [^a-zA-Z_0-9] 這個規則運算式,但初學者可能會認為除了 [a-zA-Z_0-9] 這些字元以外全部都包括了吧(含中文),但事實不然!!!

我透過 Expresso 工具驗證我的假設,請參考下圖,透過 [^\W_]+ 這個規則運算式可以取出所有過濾掉特殊字元後的結果:

相對的,將上述這個規則運算式的 ^ 符號移除後就可以用來過濾所有特殊字元,請參考以下程式碼:

string s = @"zoo13579~!多奇數位@_$#%^%$&*().,>?]";
string r = Regex.Replace(s, @"[\W_]+", "");

心得分享

雖然這只是一個很小很小的例子,不知道跟我一樣這樣寫的人多不多,我同事就問我說為什麼我想的到這種寫法,但我跟各位分享「這就是創意」,創意不是你真的比別人會想,而是你懂得比別人多,可以聯想到的知識領域比較廣,而且不時還能將不相關的人事物連結在一起。

所以我認為創意是相對的,就好像你做時光機回到兩千多年前的古代,當時的人一定會覺得你很有創意,但你真的很有創意嗎?事實上你只是拿你已知的東西在講而已,你知道別人不知道的,相對於他你就很容易成為一個有創意的人。

所以,你想要成為一個有創意的人嗎?不管哪個行業,你只要願意付出努力多加學習,自然就會成為一個有創意的人,千萬不要認為自己就是個沒創意的人,而放棄成就的機會,彼此共勉之。

相關連結