Выполните математику с помощью однострочного сценария ruby ​​gsub regex capture - PullRequest
1 голос
/ 20 июня 2011

Я пытаюсь исправить текстовый файл с субтитрами (.srt), содержащий некорректные данные, с помощью однострочного сценария ruby.Файл выглядит так:

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, и использованием магии Time.utc / strftime, предложенной @ jonas.

Вот окончательное решение (в моей системе / 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 Ответ

2 голосов
/ 20 июня 2011

У вас почти есть это, но вы хотите использовать блочную форму 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, ... это не то, что вы думаете, они за исключением блочной формы gsub:

Если замена - это строка, она будет заменена на соответствующий текст. [...] Однако в replacement специальные переменные соответствия, такие как &$, не будут ссылаться на текущее соответствие.

В блочной форме текущая строка совпадения передается как параметр, и переменные, такие как $ 1, $ 2, $ `, $ & и $’, будут установлены соответствующим образом.

Jonas Elfström прав в комментариях о вычитании 2 из секунд в "00:04:00", создающих беспорядок. Так что вы можете использовать один из временных классов для обработки вычитания. Примерно так:

(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) - это своего рода хак, чтобы обойти это. Конечно, если вы попытаетесь вычесть 2 с 00:00:00, у вас возникнут некоторые проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...