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