标题: [文本处理] [已解决]求助批处理提取转换时间和提取文字 [打印本页]
作者: tianzi 时间: 2023-12-18 14:29 标题: [已解决]求助批处理提取转换时间和提取文字
本帖最后由 tianzi 于 2023-12-18 22:21 编辑
这是一种xml字幕格式,需要转换为srt字幕格式。想法是拖入xml字幕到批处理,就自动转换xml文件所在目录中所有的xml字幕文件为srt字幕文件,并自动退出。谢谢大佬出手相助
srt格式样本- 1
- 00:01:02,875 --> 00:01:03,833
- 瞎子
-
- 2
- 00:01:04,708 --> 00:01:06,792
- 赢了赌坊这么多钱
-
- 3
- 00:01:07,333 --> 00:01:08,292
- 还不走啊
-
- 4
- 00:01:13,000 --> 00:01:14,750
- 我们来赌个大的如何
-
- 5
- 00:01:19,833 --> 00:01:21,167
- 赢了
-
- 6
- 00:01:21,250 --> 00:01:23,167
- 桌上的钱翻倍
-
- 7
- 00:01:24,000 --> 00:01:25,042
- 输了
复制代码
xml代码示例复制代码
作者: Batcher 时间: 2023-12-18 14:59
回复 1# tianzi
请把选两个XML文件打包压缩上传到网盘,我试试。
作者: tianzi 时间: 2023-12-18 15:21
回复 2# Batcher
链接: https://pan.baidu.com/s/1USpTqt4BGFzwZzlWu5Q9pw 提取码: phci 复制这段内容后打开百度网盘手机App,操作更方便哦
谢谢大佬,我手中暂时只有这一个xml文件
作者: ShowCode 时间: 2023-12-18 15:37
回复 1# tianzi
请问你是根据什么规律把39980转成00:01:02,875的?
作者: tianzi 时间: 2023-12-18 15:50
本帖最后由 tianzi 于 2023-12-18 15:52 编辑
回复 4# ShowCode
这是两个不同的文件,第一个srt不一定是由下面的xml转换而来,只是示范一下srt文件的格式
作者: ShowCode 时间: 2023-12-18 16:24
回复 5# tianzi
那么,你的实际需求是根据什么规律进行时间转换呢?
作者: pd1 时间: 2023-12-18 16:26
回复 5# tianzi
那你是要别人去猜2种格式时间的对应关系啊,阻挠问题解决啊
作者: tianzi 时间: 2023-12-18 16:35
回复 7# pd1
我也没有拿到正确的时间,猜测是1000 60 60 60这样的进率关系,xml是毫秒计数,然后需要按进率进行转换,还原成xx.xx.xx.xxx的格式
作者: idwma 时间: 2023-12-18 17:13
- #@&cls&powershell "type '%~f0'|out-string|iex"&pause&exit
- [regex]::Matches(
- (gc -enc utf8 1.xml) -join "`n",
- '<st>(\d+)</st>\s*<et>(\d+)</et>[\s\S]+?<!\[\w+\[\s*(.+?)\s*\]\]>'
- )|%{
- $m=$_.Groups
- $st=[timespan]::FromMilliseconds($m[1].value)
- $et=[timespan]::FromMilliseconds($m[2].value)
- "{0}`r`n{1:hh\:mm\:ss\,fff} --> {2:hh\:mm\:ss\,fff}`r`n{3}`r`n" -f ++$i, $st, $et, $m[3].value
- }|sc 1.srt
复制代码
作者: tianzi 时间: 2023-12-18 21:22
回复 9# idwma
大佬厉害,文件名改成1.xml后能够转出来!
作者: WHY 时间: 2023-12-18 21:46
本帖最后由 WHY 于 2023-12-18 23:26 编辑
Test.js- var arg = WSH.Arguments;
- var fso = new ActiveXObject('Scripting.FileSystemObject');
-
- if (arg.length == 0 || fso.folderExists(arg(0)) || !/\.xml$/i.test(arg(0))){
- WSH.Echo('拖入一个xml文件');
- WSH.Quit();
- }
-
- var formatTime = function(t) {
- var ms = ('' + (1000 + t % 1000)).substr(1); //毫秒
- t = Math.floor(t/1000); //总秒数
- var hh = ('' + (100 + Math.floor(t / 3600))).substr(1); //时
- var mm = ('' + (100 + Math.floor(t % 3600 / 60))).substr(1); //分
- var ss = ('' + (100 + t % 60)).substr(1); //秒
- return hh + ':' + mm + ':' + ss + ',' + ms;
- }
-
- var arr = [];
- var xml = new ActiveXObject('Microsoft.XMLDOM');
- xml.load(arg(0));
- var nodes = xml.getElementsByTagName('dia');
-
- for(var i=0; i<nodes.length; i++) {
- var st = nodes[i].selectSingleNode('st').text; //开始时间
- var et = nodes[i].selectSingleNode('et').text; //结束时间
- var t1 = formatTime(st) + ' --> ' + formatTime(et); //时间格式化
- var s1 = nodes[i].selectSingleNode('sub').text; //字幕
- arr.push(i + 1 + '\r\n' + t1 + '\r\n' + s1);
- }
-
- var dstFile = arg(0).replace(/xml$/i, 'srt'); //srt文件名
- fso.CreateTextFile(dstFile, true, true).WriteLine(arr.join('\r\n\r\n')); //保存
复制代码
作者: tianzi 时间: 2023-12-18 21:54
回复 11# WHY
厉害,可以将拖入的那个输出
作者: idwma 时间: 2023-12-18 22:13
忘记要拖放了- #@&cls&powershell "$a='%~1';type '%~f0'|out-string|iex"&pause&exit
- [regex]::Matches(
- (gc -enc utf8 $a) -join "`n",
- '<st>(\d+)</st>\s*<et>(\d+)</et>[\s\S]+?<!\[\w+\[\s*(.+?)\s*\]\]>'
- )|%{
- $m=$_.Groups
- $st=[timespan]::FromMilliseconds($m[1].value)
- $et=[timespan]::FromMilliseconds($m[2].value)
- "{0}`r`n{1:hh\:mm\:ss\,fff} --> {2:hh\:mm\:ss\,fff}`r`n{3}`r`n" -f ++$i, $st, $et, $m[3].value
- }|sc ($a -replace '.xml$','.str')
复制代码
作者: tianzi 时间: 2023-12-18 22:18
本帖最后由 tianzi 于 2023-12-18 22:20 编辑
回复 13# idwma
可以了,向你学习
作者: aloha20200628 时间: 2023-12-18 23:05
本帖最后由 aloha20200628 于 2023-12-18 23:23 编辑
也给一个cmd+jscript混编版本,存为批处理脚本如 test.cmd 或 test.bat
预览结果的用法示例》test.cmd 1.xml (亦可将 1.xml 直接托给 test.cmd)
保存结果文件的用法示例》test.cmd 1.xml>1.srt
假设输入文件 1.xml 是简中编码,内容为一楼示例样本
- @set @v=1 /*
- @echo off
- if "%~1"=="" exit/b
- findstr /bi "<st> <et> <!" "%~1" | cscript /e:jscript "%~f0" & exit/b
- */
- k=0, n=0, ws=WSH.stdin;
- while (!ws.atendofstream) {
- n++; line=ws.readline();
- t=parseInt(line.replace(/[^\d]*(\d+)</, '$1'));
- if (n == 1) { st=mssToHMS(t); }
- else if (n == 2) { et=mssToHMS(t); WSH.echo(++k +'\n'+ st +' --> '+ et); }
- else { n=0; sub=line.replace(/[^ ]+\[ (.*) \].*/, '$1'); WSH.echo(sub+'\n'); }
-
- }
- // 毫秒格式化为 hh:mm:ss,nnn
- function mssToHMS (mss) {
- var h=parseInt((mss%86400000)/3600000);
- var m=parseInt((mss%3600000)/60000);
- var s=(mss%60000)/1000;
- h=h<10 ? '0'+h : h; //补零
- m=m<10 ? '0'+m : m; //补零
- s=s<10 ? '0'+s.toFixed(3) : s.toFixed(3); //补零
- return h +':'+ m +':'+ s.replace('.', ',');
- }
复制代码
作者: tianzi 时间: 2023-12-19 15:53
回复 15# aloha20200628
谢谢大佬,我运行无结果
作者: aloha20200628 时间: 2023-12-19 16:24
回复 16# tianzi
我的测试环境是win8.1简中系统
代码存为批处理脚本文件 test.cmd
测试数据文件采用一楼提供的222行样本数据,存为1.xml,采用简中编码或记事本默认ANSI编码
命令行用法》test.cmd 1.xml 预览结果如下(共22行)- 1
- 00:00:39,980 --> 00:00:40,950
- 瞎子
-
- 2
- 00:00:41,980 --> 00:00:43,990
- 贏了賭坊這麼多錢
-
- 3
- 00:00:44,350 --> 00:00:45,180
- 還不走啊
-
- 4
- 00:00:49,870 --> 00:00:51,690
- 我們來賭個大的如何
-
- 5
- 00:00:56,390 --> 00:01:00,270
- 贏了 桌上的錢翻倍
-
- 6
- 00:01:00,350 --> 00:01:04,510
- 輸了 得留下你這隻手
-
- 7
- 00:01:06,430 --> 00:01:07,830
- 左手還是右手
-
- 8
- 00:01:08,270 --> 00:01:09,710
- 這瞎子行不行啊
-
- 9
- 00:01:26,350 --> 00:01:29,430
- 瞎子 你輸了
-
- 10
- 00:01:39,670 --> 00:01:40,509
- 全是白的
-
- 11
- 00:01:40,509 --> 00:01:42,190
- 這麼多明眼人看著
-
- 12
- 00:01:42,580 --> 00:01:44,229
- 你們就欺負我這個瞎子
-
- 13
- 00:01:50,910 --> 00:01:53,229
- 在這裡我是莊家
-
- 14
- 00:01:53,509 --> 00:01:54,750
- 我說了算
-
- 15
- 00:01:55,910 --> 00:01:56,830
- 來人
-
- 16
- 00:50:40,870 --> 00:50:42,270
- 全城設伏
-
- 17
- 00:50:42,830 --> 00:50:43,750
- 另外
-
- 18
- 00:50:43,950 --> 00:50:45,990
- 琵琶女帶人跑不了多遠
-
- 19
- 00:50:46,430 --> 00:50:47,550
- 沿途追擊
-
- 20
- 00:50:50,350 --> 00:50:52,230
- 不惜一切代價
-
- 21
- 01:09:55,390 --> 01:09:57,710
- 那年與成瞎子相識
-
- 22
- 01:09:58,790 --> 01:10:00,110
- 我十九歲
复制代码
作者: tianzi 时间: 2023-12-20 21:31
回复 17# aloha20200628
谢谢,我再试试
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |