弄了1个多小时,μ's 3rd Anniversary LoveLive! 的字幕简体化完成。
自己写了个perl程序提取繁体部分的字幕,另加好用的OpenCC,终于搞定了。
原先的字幕是繁体翻译和日文原文夹杂在一起的,如果简单粗暴地对整个文件简体化的话,日文里面的一些繁体字也会被简化,看上去就不对了。
虽然说繁体字认上去没什么压力(毕竟繁体字才是正体中文嘛),但是果然还是想做一个简体版的Lovelive! 3rd Anniversary字幕。
原始字幕为[LoveEcho!&ANK-Raws]的繁体外挂字幕。打开字幕文件后,发现好在字幕组有类似“nico - CN”这样的字幕样式名称,可以快速区别开繁体行和日文行。
但是后来发现有两个例外,一个是海爷在MC时的字幕样式名称为“umi”,另一个就是穗乃果MC时的字幕样式名称为“果”。这两个例外处理起来非常简单,简单粗暴地Command + F查找替换就能解决。
之后便是Perl登场了!
我虽然之前写过一些Perl程序,但是毕竟还是蛮久没有用过Perl了,忘掉了很多东西。
在一开始写的时候,还犯下了$out_path = chomp $out_path;这样的低级错误,还debug了好几分钟。。
回到正题,区分繁体和日文肯定就是靠正则表达式了,这里倒是非常简单,判断一下$_ =~ "CN"就行了,另外原始字幕中有以Comment的注释,Comment行里面偶尔也会夹杂CN字样,在前一个判断的基础上,再判断一次$_ =~ "Comment"就OK。
在确定包含CN而又不是Comment行之后,输出到一个临时文件print $out_file "$line:$_";保存起来。
进行完这一步之后,打卡临时文件,把里面的内容全部复制到OpenCC转换为简体中文之后,再从OpenCC复制回临时文件,接着又是Perl出马。
我们在临时文件输出的内容格式为“行号:原始数据”,我们在读取的时候,也按照这个来就行。
我们把已经转换成简体中文的数据读入到一个hash表中,以行号为key,转换之后的数据为value。
于是,根据前面的格式写出正则表达式来匹配m/(^d+):(.*)/,保存到hash里就可以用了。在读取原始字幕时,如果hash里对应行号的数据长度不为0,则输出hash里的value,不然则原封不动的输出。
Code
#! /usr/bin/env perl
# This program maybe only work with ***Love Live!μ's 3rd Anniversary LoveLive!***
use utf8;
use strict;
Usage:
print "[1] export traditional Chinese dialoguen";
print "[2] import converted Chinese dialoguenn";
my $choice = <>;
if ($choice == 1) {
print "Input origin ass file path:n";
my $file_path = <STDIN>;
open (my $ass_file, $file_path) or die "Can't open ass file.$!n";
print "Input tmp file path:n";
my $out_path = <STDIN>;
chomp $out_path;
open (my $out_file, '>', $out_path);
my $line = 1;
while (<$ass_file>) {
if ($_ =~ "CN") {
if ($_ =~ "Comment") {
}else {
print $out_file"$line:$_";
}
}
$line++;
}
}elsif ($choice == 2) {
print "Input origin ass file path:n";
my $ori_path = <STDIN>;
print "Input converted file path:n";
my $file_path = <STDIN>;
my %dialogue_table;
open (my $converted,$file_path) or die "Can't open converted file. $!n";
while (<$converted>) {
if (m/(^d+):(.*)/) {
$dialogue_table{"$1"} = $2;
}
}
open (my $ass_file, $ori_path) or die "Can't open origin ass file.$!n";
chomp($ori_path);
open (my $new_ass, '>', $ori_path.".CHS.ass") or die "Can't open new ass file.$!n";
my $line = 1;
while (<$ass_file>) {
if ($_ =~ "CN") {
if ($_ =~ "Comment") {
print $new_ass $_;
}else {
if(length($dialogue_table{"$line"}) > 0) {
print $new_ass$dialogue_table{"$line"}."n";
}else {
print $new_ass$_;
}
}
}else {
print $new_ass $_;
}
$line++;
}
}else {
goto Usage;
}