当我们有一个字幕文件,需要把里面的纯文字提出出来的时候,手动去删除其他部分会比较麻烦,所以我们可以用一小段python代码来帮我们实现这一功能。
srt文件的格式一般是这样的:
1
00:00:00,166 --> 00:00:01,499
滕王阁序
2
00:00:02,133 --> 00:00:02,999
王勃
3
00:00:05,166 --> 00:00:06,999
豫章故郡
4
00:00:07,700 --> 00:00:09,933
洪都新府
5
00:00:10,800 --> 00:00:12,733
星分翼轸
6
00:00:13,033 --> 00:00:14,933
地接衡庐
观察srt文件,会发现,我们不需要的行有:
- 数字编号行(纯数字)
- 时间跨度行(首尾都是数字)
- 空行(只有换行符’\n’)
上面的这3行是我们不需要的,所以我们需要把这3行给删掉。
我们先获取到文本文件的每一行数据,然后对纯文字行的判断,如果该行的开头不是换行符或者数字,而且结尾也不是数字的话,我们认为该行为纯文字行。
具体实现如下:
texts = []
with open("subtitle.srt", encoding="utf-8-sig") as f: # 打开字幕文件
for line in f.readlines(): # 读取字幕文件中的每一行
if line[0] not in list('\n0123456789') and line[-2] not in list('0123456789'):
# 这里是对纯文字行的判断,如果该行的开头不是换行符或者数字,而且结尾也不是数字的话,
# 我们认为该行为纯文字行
# list('\n0123456789'),是将str转换为列表,['\n','1','2',...]
# 由于每行文字的最后都会换行,所以line的最后一个字符串都是'\n',
# 所以在获取每行结尾的字符时,要用line[-2]而不是line[-1],line[-1]=='\n'
# 但这样其实也是存在一个弊端的,那就是如果纯文字的开始和结尾都是数字的话,该行文本也会被删除掉(一般不会出现这种情况)
texts.append(line) # 将筛选后的文本加入到目标列表中
texts = [text.strip() for text in texts]
# texts是一个列表,text是列表中的元素,text.strip()会去掉每个元素中,前后的空格以及换行符
# 由于每行文字的最后都有一个换行符,这里被去掉了,后面在写入文件的时候,需要在每行元素后面加上换行符'\n'
with open("content1.txt", 'w') as file:
for line in texts:
file.write(line + '\n') # 将每行文字写入文件,加上换行符'\n'
在观察了srt文件的格式之后,我们发现纯文本文字都出现在第3,7,11,15,…行,所以我们可以只提取这些行即可。
具体实现如下:
texts = []
with open('subtitle.srt', encoding="utf-8-sig") as f: # 打开文件
for lines in f.readlines(): # 获取每一行文字
texts.append(lines) # 将每行文字存放到texts列表中
texts = texts[2:len(texts):4] # 对列表进行切片,从第3个元素(下标从0开始)开始,到列表结束,每次的步长为4
texts = [text.strip() for text in texts] # 去除每行首尾的空格以及换行符
with open("content2.txt", 'w') as file:
for line in texts:
file.write(line + '\n') # 写入文件
实现效果如下:
滕王阁序
王勃
豫章故郡
洪都新府
星分翼轸
地接衡庐
虽然第一种方案的方法更为复杂,但是可以应对更为复杂的情况,比如同一个时间段内的字幕文本存在换行时(如:中英文字幕,如下),也可以进行提取,但是第二种方案就失效了。
1
00:00:51,124 --> 00:00:54,393
这是自由之城。
This is Free City.
2
00:00:55,727 --> 00:00:59,565
看看这个家伙。他是做太阳镜的。
Look at this guy. He's one of the sunglasses people.
第二种方案的优点是逻辑更为简单,当我们已知每个时间段内的字幕文件都只有一行文本时,可以采用第二种方案。
综合来说,第一种方案的适用性更广,建议采用第一种方案。