正则表达式

正则表达式

有些人在面对问题时,不经大脑便认为,“我知道,这里该用正则表达式”。现在他要面对两个问题了。

——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'