简体   繁体   中英

Transforming a string in Ruby w/ `gsub` using an array of regexps

I have a string, that I want to transform using Ruby's gsub and a TON of regexps and their resulting transformations in an array of arrays.

I like to do something like this:

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

However, the proc is not bound to the context of the gsub match, so variables like $1 and $2 are not available. I also confirm that if I just use the regexp/transformation in the process of a normal call to gsub, like:

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

the code works just fine.

Can anyone tell me a way for me to bind that proc to the context of the gsub so I can access $1 and $2 ?

Thanks

Perhaps the following or a variant would meet your needs.

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," 

I've included capture group #1 (\\p{L}+) (match one or more letters) to show how a capture group might be included that is not relevant to the proc calculation, but MatchData#captures can still be passed to the proc. (Capture group #1 is used here to ensure that the content of that capture group appears again at the specified location in the string ( \\1 )).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM