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

问题描述 投票:1回答:1

我正在尝试使用单行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

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

ruby regex shell
1个回答
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,你会遇到一些问题。

© www.soinside.com 2019 - 2024. All rights reserved.