正则表达式
有些人在面对问题时,不经大脑便认为,“我知道,这里该用正则表达式”。现在他要面对两个问题了。
——Jamie Zawinski
如果只是在字符串中进行简单的文本搜索,不要使用正则表达式,比如string['text']
。
[link]
对于简单的构建操作,使用正则表达式作为索引即可。
[link]match = string[/regexp/] # 获取匹配的内容
first_group = string[/text(grp)/, 1] # 获取匹配的分组(grp)的内容
string[/text (grp)/, 1] = 'replace' # string => 'text replace'
当你不需要分组结果时,使用非捕获组。
[link]# 差
/(first|second)/
# 好
/(?:first|second)/
避免使用 Perl 风格的、用以代表最近的捕获组的特殊变量(比如$1
、$2
等)。使用Regexp.last_match(n)
来替代。
[link]/(regexp)/ =~ string
...
# 差
process $1
# 好
process Regexp.last_match(1)
避免使用数字来获取分组。因为很难明白它们代表的含义。使用命名分组来替代。
[link]# 差
/(regexp)/ =~ string
...
process Regexp.last_match(1)
# 好
/(?<meaningful_var>regexp)/ =~ string
...
process meaningful_var
在字符类别中,只有少数几个你需要特别关心的特殊字符:^
、-
、\
、]
,所以你不需要转义[]
中的.
与中括号。
[link]
小心使用^
与$
,它们匹配的是一行的开始与结束,而不是字符串的开始与结束。如果你想要匹配整个字符串,使用\A
与\z
。(注意,\Z
实为/\n?\z/
)
[link]string = "some injection\nusername"
string[/^username$/] # 匹配成功
string[/\Ausername\z/] # 匹配失败
对于复杂的正则表达式,使用x
修饰符。这种做法不但可以提高可读性,而且允许你加入必要的注释。注意的是,空白字符会被忽略。
[link]regexp = /
start # some text
\s # white space char
(group) # first group
(?:alt1|alt2) # some alternation
end
/x
对于复杂的替换,使用sub/gsub
与哈希或区块组合的调用形式。
[link]words = 'foo bar'
words.sub(/f/, 'f' => 'F') # => 'Foo bar'
words.gsub(/\w+/) { |word| word.capitalize } # => 'Foo Bar'