> 有些人在面對問題時,不經大腦便認為,「我知道,這里該用正則表達式」。現在他要面對兩個問題了。
> ——Jamie Zawinski
* 如果只需要在字符串中簡單的搜索文字,不要使用正則表達式:`string['text']`。
* 針對簡單的字符串查詢,可以直接在字符串索引中直接使用正則表達式。
~~~
match = string[/regexp/] # 獲得匹配正則表達式的內容
first_group = string[/text(grp)/, 1] # 或得分組的內容
string[/text (grp)/, 1] = 'replace' # string => 'text replace'
~~~
* 當你不需要替結果分組時,使用非分組的群組。
~~~
/(first|second)/ # 差
/(?:first|second)/ # 好
~~~
* 不要使用 Perl 遺風的變量來表示捕獲的正則分組(如?`$1`?、?`$2`?等),它們看起來神神秘秘的。使用`Regexp.last_match[n]`。
~~~
/(regexp)/ =~ string
...
# 差
process $1
# 好
process Regexp.last_match[1]
~~~
* 避免使用數字來獲取分組。因為很難明白他們代表的意思。應該使用命名群組來替代。
~~~
# 差
/(regexp)/ =~ string
...
process Regexp.last_match[1]
# 好
/(?<meaningful_var>regexp)/ =~ string
...
process meaningful_var
~~~
* 字符類別只有幾個你需要關心的特殊字符:`^`、`-`、`\`、`]`,所以你不用轉義?`[]`?中的?`.`?或中括號。
* 小心使用?`^`?與?`$`?,它們匹配的是一行的開始與結束,不是字符串的開始與結束。如果你想要匹配整個字符串,使用`\A`?與?`\z`。(譯注:`\Z`?實為?`/\n?\z/`,使用?`\z`?才能匹配到有含新行的字符串的結束)
~~~
string = "some injection\nusername"
string[/^username$/] # 匹配
string[/\Ausername\z/] # 不匹配
~~~
* 針對復雜的正則表達式,使用?`x`?修飾符。可提高可讀性并可以加入有用的注釋。只是要注意空白字符會被忽略。
~~~
regexp = %r{
start # 一些文字
\s # 空白字元
(group) # 第一組
(?:alt1|alt2) # 一些替代方案
end
}x
~~~
* 針對復雜的替換,`sub`?或?`gsub`?可以與區塊或哈希結合使用。