> 有些人在面对问题时,不经大脑便认为,「我知道,这里该用正则表达式」。现在他要面对两个问题了。
> ——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` 可以与区块或哈希结合使用。