Новичок в регулярном выражении - PullRequest
0 голосов
/ 14 ноября 2018
def showRE(a,re)
  if a =~ re
    "#{$`}<<#{$&}>>#{$'}"
  else
    "no match"
  end
end

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

Может кто-нибудь объяснить, почему эта функция возвращает «Hello».Более конкретно, цель *? \ И как это приводит к функции, возвращающей то, что она делает.Я знаю, что ["'] находит' /" 'или' / '', а \ 1 относится к совпадению первой группы.Однако разве это не должно возвращаться -> «Он сказал« Привет »», поскольку «/» - это первая строка строки, которая представляет то, что в скобках?

1 Ответ

0 голосов
/ 15 ноября 2018

Регулярное выражение, передаваемое в качестве аргумента (который я напишу в режиме «свободного пробела», чтобы сделать его самодокументированным), выглядит следующим образом:

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\""
$' #=> ""

Значения этих переменныхприведены в этом документе .Вы увидите, что:

  • $ `содержит строку слева от последнего успешного совпадения;
  • $ & содержит строку, сопоставленную с последним успешным совпадением;и
  • $ 'содержит строку справа от последнего успешного совпадения.

Таким образом, мы имеем (и возвращаем)

"#{"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 (делая это .*?).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...