【问题标题】:What's the Ruby equivalent of Perl's s{}{}e?Perl 的 s{}{}e 的 Ruby 等价物是什么?
【发布时间】:2016-06-12 16:05:40
【问题描述】:

我正在尝试重写一个命令,用不同目录中的相同文件替换输出文件,从而构建翻译映射。在 Perl 中,我可以这样做:

s{(-o|--out)\s((?:\S+\/)?(\S+))}{ "$1 " . ($m{$2}="foo/$3") }eg

我不清楚如何在 Ruby 下做同样的事情,因为:

"-out AAA -out yeah/BBB".
gsub(/((?:\s|^)-out)\s+((?:\S+\/)?(\S+))/) { |f|
  "#{f[1]} #{m[f[2]] = "temp/#{f[3]}"}"
}

结果

"o temp/t- temp/u"

因为'm'是匹配字符串,不是匹配对象,所以#{m[1]}只是匹配字符串的第二个字符。

我不想使用$1$2,因为 Rubocop 说它们是邪恶的,而且我不想使用“Regexp.last_match”,因为它非常冗长,并且会将这种单行代码变成一个do-block。

是否没有内置函数可以将匹配对象作为参数?

【问题讨论】:

  • 您可以将命名匹配与 gsub 一起使用,因此您不必依赖 $1$2。像任何其他块参数一样将它们传递给块。

标签: ruby regex perl language-comparisons


【解决方案1】:

一旦你不想像在 perl 中那样使用$1,你可以使用命名匹配:

"-out AAA -out BBB".gsub(/(?<leading>\s|^)(?<out>-out)\s+(?<rest>\S+)/) do
  "#{$~[:leading]}#{$~[:out]} BLOCK"
end
#⇒ "-out BLOCK -out BLOCK"

另一个选择是关闭 rubocop,因为您知道自己在做什么:

#rubocop:disable Style/PerlBackrefs
"-out AAA -out BBB".gsub(/(\s|^)(-out)\s+(\S+)/) do
  "#{$1}#{$2} BLOCK"
end
#rubocop:enable Style/PerlBackrefs

【讨论】:

  • 谢谢,我最终选择了后者,但我从您的回复中推断没有提供匹配对象作为其参数的 gsub?
  • 很遗憾,没有。或者,有人可能会认为这是设计使然,因为您始终可以访问全局 $~,返回最后一次成功的匹配。由于 ruby​​ 是单线程设计的,gsub 返回最后一个匹配项似乎是多余的。 (以上只是我的假设。)
猜你喜欢
  • 1970-01-01
  • 2012-02-02
  • 2012-03-20
  • 2011-03-25
  • 2023-04-04
  • 1970-01-01
  • 2011-03-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多