Преобразование строки в Ruby с помощью gsub с использованием массива регулярных выражений - PullRequest
2 голосов
/ 02 мая 2019

У меня есть строка, которую я хочу преобразовать, используя gsub Руби и ТОНН регулярных выражений и их результирующие преобразования в массиве массивов.

Мне нравится делать что-то вроде этого:

MY_REGEXPS = [
  [ 
    /^(\d-\d:) (SINGLE|DOUBLE|TRIPLE)/, 
    proc { "#{$1} #{$2.capitalize}," }
  ],
  #....Many for regexp/transformation pairs
]

my_string = "0:0 SINGLE (Line Drive, 89XD)"

MY_REGEXPS.inject(my_string) do |str, regexp_pair|
  str.gsub(regexp_pair.first, &regexp_pair.last)
end

Однако процедура не связана с контекстом сопоставления gsub, поэтому такие переменные, как $1 и $2, недоступны. Я также подтверждаю, что если я просто использую регулярное выражение / преобразование в процессе обычного вызова gsub, например:

my_string.gsub(/^(\d-\d:) (SINGLE|DOUBLE|TRIPLE)/) do
  "#{$1} #{$2.capitalize},"
end

код работает просто отлично.

Может кто-нибудь сказать мне способ привязать этот процесс к контексту gsub, чтобы я мог получить доступ к $1 и $2?

Спасибо

1 Ответ

1 голос
/ 03 мая 2019

Возможно, следующий вариант или вариант будет соответствовать вашим потребностям.

MY_REGEXPS = [
  [ 
    /^(\p{L}+) (\d:\d) (SINGLE|DOUBLE|TRIPLE) \1/i,
    proc { |_,v2,v3| "#{v2} #{v3.capitalize}," }
  ],
]

my_string = "dog 1:2 single dog (Line Drive, 89XD)"

MY_REGEXPS.inject(my_string) do |s,(re,p)|
  p.call(*s.match(re).captures)
end
  #=> "1:2 Single," 

Я включил группу захвата # 1 (\p{L}+) (соответствует одной или нескольким буквам), чтобы показать, как можно включить группу захвата, которая не имеет отношения к расчету процедур, но MatchData # захватывает может все еще быть переданным в proc. (Группа захвата № 1 используется здесь, чтобы гарантировать, что содержимое этой группы захвата снова появится в указанном месте в строке (\1)).

...