2015年8月30日 星期日

Regular Expression 喜蝦密?! 來研究一下...

知識參考來源: Introducing Regular Expressions, by Michael Fitzgerald, O’Reilly
現今 Unix 系統及許多程式語言都使用 regular expression (常規表示式?) 當做字串對應或搜尋的 pattern。 pattern 中文不好翻譯, 使用實質上就如字面原意像布料的一小塊花色樣式一樣, 但說成花色, 樣式, 樣版, 模型感覺都不太搭! Regular Expression 範例:
 ^((d{3})|^d{3}[.-]?)?d{3}[.-]?d{4}$
.... 嗯嗯! 目前看起來是火星文  (聽說是北美電話號碼的規則... o_o!!!)
這個網址可以比較資料是否符合指定的 regular expression: regexpal.com
以下 regular expression 範例:
 [0-9]
代表0~9之間的任何單一數字, 其中左右中括號(square bracket) 是 metacharacters, 而 metacharacter 在 regular expression 中是有特殊用法的保留字。範例 [0-9] 在 regular expression 中稱為 character class, 有時也稱做 character set。 由此引申其他用法, 如下例:
 [012589]
代表符合 0,1,2,5,8,9 之中的任一數字的單一數字。 前面講的是單一數字的對應, 那要對應很多數字如電話號碼可能會想到要這樣寫:
 [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9][0-9]
此時填入 555-12345 就符合規則了, 不過這樣 regular expression 就變得冗長, 所以又提供一種寫法叫 character shorthand, 可以用 d 來代表 [0-9], regular express 就可改寫為
 ddd-ddddd
對應於 d 代表單一數字, D 被設定為代表單一非數字字元, 如果電話號碼規則寫成
 dddDddddd
那原先 555-12345 是沒問題的, 不過如果輸入 555a12345 也是算是符合規則的而 555812345 就不合規則了。 另外一個常用的特殊字元是句點 . (dot) 代表任合字元 (非特殊情況下通常不包含換行字元 u000A), regluar expression 寫成:
 ddd.ddddd
那不論 555-12345, 555a12345, 555812345, 555%12345, 555|12345, ... 都算符合規則。
Capturing Groups 和 Back References:
 (d)d1
以上寫法, 加了小括號 (parentheses) 的 (d) 為 capturing group; 1 則為 back reference 代表 (d) 所捕獲的數字。 所以 707 符合以上規則, 而 706 因為第三個數字與第一個數字不同所以不符合規則。
Quantifiers:
 d{3}-?d{3}-?d{4}
包了數字的大括號(curly braces) {3} 是一種 quantifier, 代表前面的字元重複3次; 問號 ? 則代表前面的那個字元是 optional 可有可無的。 所以這樣的表示式為334數字組合的電話號碼, 中間有沒有加 - (hyphen) 都沒關係。 其他常用的 quantifiers 還有: +: 加號(plus sign), 代表至少一個 *: 星號(asterisk), 代表沒半個或很多個都可以 應用 quantifier, 以下 regular expression:
 (d{3,4}[.-]?)+
+ 號控制 capturing group (d{3,4}[.-]?) 的內容至少要填入一次, {3,4} 控制 d 要填入最少3字最多4字, ? 號控制僅能填入 . 或 - 字元但不填也可。 以下更複雜的一個例子展示電話區域號碼可加或不加括號的寫法, 也說明特殊保留字元的括號如何當成文字字元處理:
 ^((d{3})|^d{3}[.-]?)?d{3}[.-]?d{4}$
稍微拆開來看 ^ ((d{3})  |  ^d{3} [.-]?)?  d{3}  [.-]?  d{4}  $
最前面的 ^ 號代表只找字串頭符合的, 最後面的 $ 號代表只找字串尾符合的; 兩者並用則表示整個字串要完全符合規則, (...)? 為區域號部份, 其中 ? 號代表區域號可有可無, d{3} 代表區號後要接3個數字, [.-]? 代表3個數字後只能接 . 或 - 字元, 其後的 ? 號代表不填也可, d{4} 代表號碼最後要再填4個數字 區號 capturing group 中間的 | 號代表符合 (d{3}) 或 ^d{3}[.-]? 其中之一即可, (d{3}) 代表用小括號刮起來的3個數字 ^d{3}[.-]? 代表這個 group 內開頭要3個數字,然後可選填 . 或 - 或字元不填
Negated Class 在 character class 的中括號後面第一個字元填入 ^ 號, 表示是要找不符合的, 例如
 [^d] 等同於 [^0-9] 等同於 D

Matching Word and Non-Word Characters Word 的 shorthand 為 w 用起來和 D 似乎有點像, 差別在於 w 只包含大小寫和數字, 而 D 是涵蓋數字以外的所有符號, 連空白字元也算。
 w 等同於 [a-zA-Z0-9]
 W 等同於 [^w] 等同於 [^a-zA-Z0-9]

Character Shorthand 列表
Character Shorthand 說明
aAlert
bWord boundary
[b]Backspace character
BNon-word boundary
cxControl character
bWord boundary
dDigit character
DNon-digit character
dxxxDecimal value for a character
fForm feed character
rCarriage return
nNewline character
oxxxOctal value for a character
sSpace character   (等於[ tnr])
SNon-space character
tHorizontal tab character
vVertical tab character
wWord character
WNon-word character
Null character
xxxHexadecimal value for a character
uxxxxUnicode value for a character

沒有留言:

張貼留言