匹配中文的正则表达式: [\u4e00-\u9fa5]
前天我在看美剧《权力的游戏》的时候,发现没字幕,于是乎自己从网上下载字幕匹配到视频;发现网上的字幕都是比较全面的,中英双语字幕,但是对我来说,中文字幕是我不想要的,我要强迫自己只看英文字幕,但是在播放器设置上又无法只显示英文;所以只有通过修改字幕文件,将中文删除喽;
本以为一个正则表达式 * 就可以把中文给匹配掉的,但事情并没有那么简单,因为一般带中文的文件有GBK,Unicode,UTF-8,UTF-16……好几种。所以在读取文件和写入文件的时候都需要指定编码格式.
一开始我以为10集的字幕都是同一种编码格式的(Unicode)(可以通过另存为查看到文件的编码格式;),所以我就用unicode解析文件,发现第一个字幕文件可以修改成功,但是后来的9个字幕文件都出现了乱码;查看发现后面的几个文件的编码不是Unicode,有UTF-8和ANSI两种,这时候我就想了,怎么样可以通过一个程序得到一个文件的编码格式呢, 这时候就省力了,最后百度了一下,果然找到了答案;
1.字幕文件片段:
Dialogue: 0,0:54:02.00,0:54:04.86,*Default,NTP,0000,0000,0000,,我欠您一条命 先生\N{\fs16}I owe you my life, ser.{\r}
Dialogue: 0,0:54:04.90,0:54:06.53,*Default,NTP,0000,0000,0000,,我深感荣幸\N{\fs16}The honor is mine,{\r}
Dialogue: 0,0:54:06.57,0:54:08.77,*Default,NTP,0000,0000,0000,,女王陛下\N{\fs16}my queen.{\r}
Dialogue: 0,0:54:12.14,0:54:14.41,*Default,NTP,0000,0000,0000,,你认识他?\N{\fs16}You know this man?{\r}
Dialogue: 0,0:54:14.44,0:54:16.24,*Default,NTP,0000,0000,0000,,我认识他\N{\fs16}I know him{\r}
其中,我要去掉文件的中文字符;也就是介于0000,,和\N{\fs16}之间的这部分;
2.代码片段为:
niuStr = lineStr.replaceAll("(0000,,)(.*)[\u4e00-\u9fa5]*(.)*(\\\\N(\\{\\\\fs16\\})*)", "$1");
其中,[\u4e00-\u9fa5]是匹配一个中文的正则表达式;
3.另外还有一些字幕的格式是这样的:
Dialogue: 0,0:51:52.55,0:51:54.42,正文,,0,0,0,,哦 好的 好的 这样感觉很——\N{\fs16}Oh, yes. Yes, this will do nic--{\r}
Dialogue: 0,0:51:54.45,0:51:56.55,正文,,0,0,0,,啊!\N{\fs16}ah!{\r}
Dialogue: 0,0:51:56.59,0:51:58.76,正文,,0,0,0,,趴上去\N{\fs16}On the stump.{\r}
Dialogue: 0,0:52:04.43,0:52:08.07,正文,,0,0,0,,你觉得你是这里面脑瓜子最灵光的?\N{\fs16}You think you're the smartest man there is.{\r}
4.修改字幕的代码:
niuStr = lineStr.replaceAll("([\u4e00-\u9fa5]*,,0,0,0,,)(.*)[\u4e00-\u9fa5]*(.)*(\\\\N(\\{\\\\fs16\\})*)", "$1");
第一个[\u4e00-\u9fa5]匹配正文两个字,第二个[\u4e00-\u9fa5]匹配中文字幕;
5.上面提到修改文件时还要知道文件的编码格式,我在网上找了一个简单的判断程序,虽然功能有待完善,但已经基本满足我的需求:
/*这个方法用来获取文件的编码格式,功能有限,只能识别UTF-8,Unicode,UTF-16BE如果都不满足,默认返回编码方式为GBK*/
public static String getFileEncoding(File file) throws Exception {
BufferedInputStream bin = new BufferedInputStream(new FileInputStream(file));
int p = (bin.read() << 8) + bin.read();//核心代码
String encoding = null;
switch (p) {
case 0xefbb:
encoding = "UTF-8";
break;
case 0xfffe:
encoding = "Unicode";
break;
case 0xfeff:
encoding = "UTF-16BE";
break;
default:
encoding = "GBK";
}
System.out.println(encoding);
return encoding;
}
这部分代码完成获取编码格式的功能;
6.完整的程序代码我给列出来:
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.Test;
public class TrimChineseCaptions {
/**
*除去中文字幕
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
File srcDir = new File("E:\\BaiduYun\\权力的游戏无删减\\字幕\\[zmk.tw]Game.Of.Thrones.S03");// 字幕文件夹
File[] files = srcDir.listFiles();
for (File file : files) {// 遍历修改
File srcFile = file;
File destFile = null;
if (srcFile.exists()) {
String fileName = srcFile.getName();
destFile = new File(srcFile.getParentFile(), fileName.substring(0, fileName.length() - 4) + "-TrimedChi-S3.ass");//新文件的文件名
}
String encoding = getFileEncoding(file);// 获取文件的编码格式
BufferedReader bufRer = new BufferedReader(new InputStreamReader(new FileInputStream(srcFile), encoding));
BufferedWriter bufWer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(destFile), encoding));
String lineStr = null;//读取的string
String niuStr = null;//替换后的string
while ((lineStr = bufRer.readLine()) != null) {
niuStr = lineStr.replaceAll("([\u4e00-\u9fa5]*,,0,0,0,,)(.*)[\u4e00-\u9fa5]*(.)*(\\\\N(\\{\\\\fs16\\})*)", "$1");
if (niuStr.equals(lineStr)) {
niuStr = lineStr.replaceAll("(0000,,)(.*)[\u4e00-\u9fa5]*(.)*(\\\\N(\\{\\\\fs16\\})*)", "$1");
}
// System.out.println(niuStr);
bufWer.write(niuStr);
bufWer.newLine();
bufWer.flush();
}
bufWer.close();
bufRer.close();
}
}
/**
* 这个方法用来获取文件的编码格式,功能有限,只能识别UTF-8,Unicode,UTF-16BE如果都不满足,默认返回编码方式为GBK
*
* @param file
* @return encoding : 文件的编码格式
* @throws Exception
*/
public static String getFileEncoding(File file) throws Exception {
BufferedInputStream bin = new BufferedInputStream(new FileInputStream(file));
int p = (bin.read() << 8) + bin.read();//核心代码
String encoding = null;
switch (p) {
case 0xefbb:
encoding = "UTF-8";
break;
case 0xfffe:
encoding = "Unicode";
break;
case 0xfeff:
encoding = "UTF-16BE";
break;
default:
encoding = "GBK";
}
System.out.println(encoding);
return encoding;
}
// @Test
public void test_o2() {// 匹配中文的正则表达式测试
String str = "123abc你好efc";
String reg = "[\u4e00-\u9fa5]";// 匹配中文
Pattern pat = Pattern.compile(reg);
Matcher mat = pat.matcher(str);
String repickStr = mat.replaceAll("");
System.out.println("去中文后:" + repickStr);
}
}
版权声明:本文为Love_Legain原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。