在单行ruby脚本gsub regex捕获上执行数学运算

时间:2011-06-19 22:13:11

标签: ruby regex shell

我正在尝试使用单行ruby脚本修复字幕(.srt)文本文件,该文件包含一些不正确的数据。该文件如下所示:

53
00:03:52,835 --> 00:03:54,835
Boss?... BOSS?!

54
00:03:54,845 --> 00:03:56,990


55
00:0 --> 00:03:58,490
Go!

I want the 55 stanza to look like this:

55
00:03:56,490 --> 00:03:58,490
Go!

第一个时间戳从第二个时间戳中扣除,但减去2秒。

这是我的尝试,但无效:

ruby -pi.bak -e 'gsub(/(\d{2}):(\d) --> (\d{2}):(\d{2}):(\d{2}),(\d{3})/, "#{$3}:#{$4}:#{$5},#{$6} --> #{$3}:#{$4}:#{$5.to_i - 2},#{$6}")' *.srt

修改

因此,正如响应者所指出的,ruby 1.9.2不支持通过$ 1,$ 2等语法访问正则表达式捕获。

我最终使用的修复程序是切换回ruby 1.8.x,并使用带有块的gsub作为@mu建议,并使用@jonas建议的Time.utc / strftime魔法。

这是最终解决方案(在我的系统/ usr / bin / ruby​​上是1.8.6):

/usr/bin/ruby -pi.bak -e 'gsub(/(\d{2}):(\d) --> (\d{2}):(\d{2}):(\d{2}),(\d{3})/) {"#{(Time.utc(1970,1,1, $3,$4,$5) - 2).strftime("%H:%M:%S")},#{$6} --> #{$3}:#{$4}:#{$5},#{$6}"}' *.srt

我正在使用格式正确的字幕观看我的电影。谢谢你们:))

1 个答案:

答案 0 :(得分:2)

你几乎拥有它,但你想使用block form of gsub而不是两个参数形式,我认为你的减法是--->的错误:

ruby -pi.bak -e '$_.gsub(/(\d{2}):(\d) --> (\d{2}):(\d{2}):(\d{2}),(\d{3})/) { "#{$3}:#{$4}:#{$5.to_i - 2},#{$6} --> #{$3}:#{$4}:#{$5},#{$6}" }' *.srt

Ruby 1.8不需要$_的块形式gsub,但1.9。全局$1$2,......不是您认为的except in block form of gsub

  

如果replacement是一个String,它将替换匹配的文本。 [...]但是,在replacement范围内,特殊匹配变量(例如&$)不会引用当前匹配。

     

在块形式中,当前匹配字符串作为参数传入,并且将适当地设置诸如$ 1,$ 2,$`,$&和$'之类的变量。

乔纳斯·埃尔斯特罗姆(JonasElfström)在关于从“00:04:00”中的秒数减去2的评论中是对的。因此,您可能希望使用其中一个时间类来处理减法。像这样:

(Time.utc(1970,1,1, $3,$4,$5) - 2).strftime('%H:%M:%S')

取代你的#{$3}:#{$4}:#{$5.to_i - 2},#{$6}应该可以解决问题。 Time.utc希望使用完整的日期时间,而不仅仅是一段时间,因此使用Unix时代(1970-01-01)是一个很好的解决方法。当然,如果你试图从00:00:00减去2,你会遇到一些问题。