def showRE(a,re)
if a =~ re
"#{$`}<<#{$&}>>#{$'}"
else
"no match"
end
end
showRE('He said "Hello"', /(["']).*?\1/)
#=> "He said <<\"Hello\">>"
有人可以解释为什么此函数返回“ Hello”。更具体地说,*?\的目的以及如何使函数返回其作用。我知道[“']找到'/''或'/',\ 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 (通过使其变为.*?
)。