需要浏览WEBVTT(带有简单垂直字幕位置信息的文本文件)并计算行数和时间戳旁边的返回值
我对此并不陌生,并尝试过查找和替换正则表达式,但这没用
我在带字幕的文件中拥有此内容:
WEBVTT
00:00:00.000 --> 00:00:02.160
Hello World
I am James
00:00:02.185 --> 00:00:04.990
Welcome to my Show!
00:00:12.038 --> 00:00:14.530
This is our new season.
We hope you enjoy the show
00:00:19.580 --> 00:00:21.840
This is the first episode.
并且希望脚本检查带有时间戳的每个部分并返回:
WEBVTT
00:00:00.000 --> 00:00:02.160 align:middle line:84%
Hello World
I am James
00:00:02.185 --> 00:00:04.990 align:middle line:90%
Welcome to my Show!
00:00:12.038 --> 00:00:14.530 align:middle line:84%
This is our new season.
We hope you enjoy the show!
00:00:19.580 --> 00:00:21.840 align:middle line:90%
This is the first episode.
如果只有一行,那么时间戳旁边的返回值将是
align:middle line:90%
其他align:middle line:84%
答案 0 :(得分:1)
执行批处理文件的Windows命令处理器cmd.exe
专用于运行命令和应用程序。它不适用于在文本文件中进行修改。还有许多其他脚本语言具有可轻松修改文本文件的功能,例如VBScript,JScript,PowerShell,Python,Perl等。因此,为此任务使用Windows命令处理器是最糟糕的决定,这可能由某人做出
但是,使用 Dave Benham 编写的JREPL.BAT还是一个容易完成的任务,这是一个批处理文件/ JScript混合程序,可以使用JScript在文件上运行正则表达式替换
@echo off
if not exist "%~dp0jrepl.bat" goto :EOF
if not exist "WEBVTT" goto :EOF
call "%~dp0jrepl.bat" "(\d{2}:\d{2}:\d{2}\.\d{3} --\> \d{2}:\d{2}:\d{2}\.\d{3})(\r?\n[^\r\n]+\r?\n[^\r\n])" "$1 align:middle line:84%%$2" /M /F "WEBVTT" /O -
call "%~dp0jrepl.bat" "(\d{2}:\d{2}:\d{2}\.\d{3} --\> \d{2}:\d{2}:\d{2}\.\d{3})(\r?\n[^\r\n])" "$1 align:middle line:90%%$2" /M /F "WEBVTT" /O -
批处理文件首先检查当前目录中是否存在名为WEBVTT
的文件,如果此条件不成立,则立即退出,请参阅Where does GOTO :EOF return to?
批处理文件 JREPL.BAT 必须与具有上述代码的批处理文件存储在同一目录中。因此,该批处理文件将检查 JREPL.BAT 是否确实存在于该批处理文件的目录中,如果此条件不成立,则退出。
然后 JREPL.BAT 两次用于在文件WEBVTT
上运行两个正则表达式替换,以将其内容更改为所需格式。
让我们来看看第一个搜索表达式:
(\d{2}:\d{2}:\d{2}\.\d{3} --\> \d{2}:\d{2}:\d{2}\.\d{3})(\r?\n[^\r\n]+\r?\n[^\r\n])
(
... )
...定义标记组。在第一个标记组中由表达式找到的字符串在替换字符串中用$1
向后引用,以使找到的和匹配的字符串的这一部分保持不变。标记组内的正则表达式用于在行内的任意位置使用诸如00:00:02.185 --> 00:00:04.990
之类的字符串来查找行。
\d{2}
...表示必须为正数找到两位。
\.
...点表示任何字符,因此必须用反斜杠转义才能将其解释为文字字符。
\d{3}
...表示必须为正数找到三位数。
\>
... >
也需要用反斜杠转义以将其解释为文字字符。
(
... )
...定义第二个标记组。在第二个标记组内的表达式中找到的字符串在替换字符串中用$2
进行了反向引用,以使找到的字符串的这一部分也保持不变。
\r?\n
...例如00:00:02.185 --> 00:00:04.990
之后必须有一个换行符,并且可以有一个回车符。
[^\r\n]+
...下一行必须包含一个或多个字符,不能作为回车符或换行符。因此,搜索表达式在下一行为空行时为负。请注意,仅包含空格/制表符的行不是空行。由于只包含空格字符,因此为空行,但不是空行。
\r?\n[^\r\n]
...最后,必须再有一个DOS / Windows或UNIX行结尾,并且下一行还必须包含一个正匹配字符。
因此,第一个搜索表达式将带有字幕的行与带有两行的字幕匹配。
因此,第一个替换字符串包含84%
,其中百分号必须再加上一个百分号,因为否则Windows命令处理器会将%
解释为环境变量或批处理文件参数引用的开头
第二个搜索表达式与第一个搜索表达式相似,但是仅在时间值不的行上为正,第二个时间值之后已经有更多的文本,并且下面还有一行空行。
两个正则表达式都是多行表达式,需要 JREPL 选项/M
。
要了解所使用的命令及其工作方式,请打开命令提示符窗口,在其中执行以下命令,并非常仔细地阅读每个命令显示的所有帮助页面。
call /?
...也解释了%~dp0
...参数0的驱动器和路径是批处理文件本身。echo /?
goto /?
if /?
jrepl.bat /?
答案 1 :(得分:1)
可以使用适当的方法以相对简单的方式在批处理文件(或任何其他编程语言)中解决此问题:
编辑2019-01-07: 带有感叹号的问题已解决
@echo off
setlocal DisableDelayedExpansion
(
echo WEBVTT
echo/
set "i=0"
for /F "skip=2 tokens=1* delims=:" %%a in ('findstr /N "^" input.txt') do (
set /A i+=1
call set "line[%%i%%]=%%b"
if "%%b" equ "" (
set /A "line=90-!!(i-3)*6"
setlocal EnableDelayedExpansion
echo !line[1]! align:middle line:!line!%%
for /L %%i in (2,1,!i!) do echo(!line[%%i]!
endlocal
set "i=0"
)
)
set /A "line=90-!!(i-2)*6"
setlocal EnableDelayedExpansion
echo !line[1]! align:middle line:!line!%%
for /L %%i in (2,1,!i!) do echo(!line[%%i]!
) > output.txt
读取行并将其存储在数组中,直到出现空行。在那一刻,所有行都被输出,并且附加数据被添加到第一行。当部分中的行数为3(包括最后一个空行)时,有些奇怪的算术表达式仅从90中减去6。有关更多详细信息,请参见SET /?
。