正则表达式初学者

时间:2018-11-14 19:19:23

标签: ruby-on-rails ruby regex

def showRE(a,re)
  if a =~ re
    "#{$`}<<#{$&}>>#{$'}"
  else
    "no match"
  end
end

showRE('He said "Hello"', /(["']).*?\1/)
  #=> "He said <<\"Hello\">>"

有人可以解释为什么此函数返回“ Hello”。更具体地说,*?\的目的以及如何使函数返回其作用。我知道[“']找到'/''或'/',\ 1指的是第一组的匹配项。但是,那不应该返回->“他说你好”是因为“ /”是表示括号中字符串的第一行吗?

1 个答案:

答案 0 :(得分:3)

作为参数传递的正则表达式(我将以“自由间距”模式编写,以使其具有自我说明性),如下所示:

r = /
    (      # start capture group 1
    ["']   # match a double or single parenthesis (a "character class")
    )      # end capture group 1
    .*     # match zero or more (`*`) characters (any characters)
    ?      # make the foregoing match (.*) lazy
    \1     # match the contents of capture group 1
    /x     # free-spacing regex definition mode

str = 'He said "Hello"'
  #=> "He said \"Hello\""
str =~ r
  #=> 8 (we have a match beginning at str[8])

由于str =~ r是“真实的”,我们评估

"#{$`}<<#{$&}>>#{$'}"
   => "He said <<\"Hello\">>"

此处的关键是此表达式中有三个全局变量:

$` #=> "He said "
$& #=> "\"Hello\""
$' #=> ""

这些变量的含义在this doc中给出。您将看到:

  • $`包含最后一次成功匹配左侧的字符串;
  • $&包含最后一次成功匹配的字符串;和
  • $'包含最后一次成功匹配右边的字符串。

所以我们有(并返回)

"#{"He said "}<<#{"\"Hello\""}>>#{""}"
  #=> => "He said <<\"Hello\">>"

我们也可以使用类方法Regexp::last_match

last_match = Regexp.last_match
  #=> #<MatchData "\"Hello\"" 1:"\"">

last_match是类MatchData的实例。该类包含许多有用的方法,包括那些返回上述三个全局变量的值的方法:

last_match.pre_match  #=> "He said "
last_match[0]         #=> "\"Hello\""
last_match.post_match #=> ""

我不能说为什么正则表达式中的匹配.*被设置为 lazy (通过使其变为.*?)。