【问题标题】:Transforming a string in Ruby w/ `gsub` using an array of regexps使用正则表达式数组在 Ruby 中使用“gsub”转换字符串
【发布时间】:2019-05-02 18:25:42
【问题描述】:

我有一个字符串,我想使用 Ruby 的 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

但是,proc 没有绑定到 gsub 匹配的上下文,所以像 $1$2 这样的变量不可用。我还确认,如果我只是在正常调用 gsub 的过程中使用正则表达式/转换,例如:

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

代码运行良好。

谁能告诉我一种方法让我将该 proc 绑定到 gsub 的上下文,以便我可以访问 $1$2

谢谢

【问题讨论】:

  • 正则表达式与字符串不匹配:刚刚更改了my_string = "0-0: SINGLE (Line Drive, 89XD)",它对我有用:)
  • 有些人可能将此称为XY problem。你已经把注意力集中在你最后一句话的主题上,可能已经忘记了你可能通过其他方式实现的最终目标。有时我们都会被吸进那个洞。这当然是要提防的。

标签: ruby-on-rails regex ruby binding proc


【解决方案1】:

也许以下或变体将满足您的需求。

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}+)(匹配一个或多个字母)以显示如何包含与 proc 计算无关的捕获组,但 MatchData#captures 仍可传递给 proc . (此处使用捕获组 #1 以确保该捕获组的内容再次出现在字符串中的指定位置 (\1))。

【讨论】:

  • 非常聪明,与我最终得到的解决方案基本相同,很高兴得到一些外部确认。谢谢!
猜你喜欢
  • 1970-01-01
  • 2015-11-30
  • 1970-01-01
  • 2015-05-29
  • 2018-12-30
  • 1970-01-01
  • 1970-01-01
  • 2016-08-13
  • 1970-01-01
相关资源
最近更新 更多