用于检测字幕错误的正则表达式

时间:2014-03-04 08:15:18

标签: regex

我有一些字幕问题,我需要一种方法来检测特定的错误。我认为正则表达式会有所帮助,但需要帮助解决这个问题。在这个SRT格式的字幕示例中,第13行结束于00:01:10,130,第14行从00:01:10:129结束。

13
00:01:05,549 --> 00:01:10,130
some text here.

14
00:01:10,129 --> 00:01:14,109
some other text here.

问题是下一行在当前的一行结束之前无法开始 - 当发生这种情况时,嵌入算法不起作用。我需要检查我的SRT文件并手动更正,但是每个小时长的大约20个视频中手动查找这个并不是一个选项。特别是因为我需要'昨天'(:

SRT字幕的格式非常具体:

XX 
START --> END 
TEXT
EMPTY LINE

[line number (digits)][new line character]
[start and end times in 00:00:00,000 format, separated by _space__minusSign__minusSign__greaterThenSign__space_][new line character]
[text - can be any character - letter, digit, punctuation sign.. pretty much anything][new line character]
[new line character]

我需要检查END时间是否大于以下字幕的START时间。帮助将不胜感激。

PS。我可以使用Notepad ++,Eclipse(Aptana),python或javascript ...

2 个答案:

答案 0 :(得分:1)

正则表达式可以用于实现你想要的东西,据说,他们不能自己做。正则表达式用于匹配模式而不是数字范围。

如果我在哪里,我会做的如下:

  1. 解析文件并将开始时间放在一个数据结构中(称之为DS_A),将文本放在另一个数据结构中(称之为DS_B)。
  2. 按升序排序DS_A。这应该保证您不会有重叠的范围。 (This之前的SO帖子应该指向正确的方向。)
  3. 在您的文件中迭代并写下以下内容:j DS_A[i] --> DS_A[i + 1] <newline> DS_B[j]其中iDS_A的循环计数器,jDS_B的循环计数器

答案 1 :(得分:0)

我最后写了一个短脚本来解决这个问题。这是:

# -*- coding: utf-8 -*-
from datetime import datetime
import getopt, re, sys

count = 0
def fix_srt(inputfile):
  global count
  parsed_file, errors_file = '', ''
  try:
    with open( inputfile , 'r') as f:
      srt_file = f.read()
      parsed_file, errors_file = parse_srt(srt_file)
  except:
    pass
  finally:
    outputfile1 = ''.join( inputfile.split('.')[:-1] ) + '_fixed.srt'
    outputfile2 = ''.join( inputfile.split('.')[:-1] ) + '_error.srt'
    with open( outputfile1 , 'w') as f:
      f.write(parsed_file)
    with open( outputfile2 , 'w') as f:
      f.write(errors_file)
    print 'Detected %s errors in "%s". Fixed file saved as "%s"
           (Errors only as "%s").' % ( count, inputfile, outputfile1, outputfile2 )

previous_end_time = datetime.strptime("00:00:00,000", "%H:%M:%S,%f")
def parse_times(times):
  global previous_end_time
  global count
  _error = False
  _times = []
  for time_code in times:
    t = datetime.strptime(time_code, "%H:%M:%S,%f")
    _times.append(t)

  if _times[0] < previous_end_time:
    _times[0] = previous_end_time
    count += 1
    _error = True
  previous_end_time = _times[1]

  _times[0] =  _times[0].strftime("%H:%M:%S,%f")[:12]
  _times[1] = _times[1].strftime("%H:%M:%S,%f")[:12]

  return _times, _error

def parse_srt(srt_file):
  parsed_srt = []
  parsed_err = []
  for srt_group in re.sub('\r\n', '\n', srt_file).split('\n\n'):
    lines = srt_group.split('\n')
    if len(lines) >= 3:
      times = lines[1].split(' --> ')
    correct_times, error = parse_times(times)
    if error:
      clean_text = map( lambda x: x.strip(' '), lines[2:] )
      srt_group = lines[0].strip(' ') + '\n' + ' --> '.join( correct_times ) + '\n' + '\n'.join( clean_text )
      parsed_err.append( srt_group )
    parsed_srt.append( srt_group )
  return '\r\n'.join( parsed_srt ), '\r\n'.join( parsed_err )

def main(argv):
  inputfile = None
  try:
    options, arguments = getopt.getopt(argv, "hi:", ["input="])
  except:
    print 'Usage: test.py -i <input file>'

  for o, a in options:
    if o == '-h':
      print 'Usage: test.py -i <input file>'
      sys.exit()
    elif o in ['-i', '--input']:
      inputfile = a
  fix_srt(inputfile)

if __name__ == '__main__':
  main( sys.argv[1:] )

如果有人需要它,例如将代码保存为srtfix.py,并从命令行使用它:

python srtfix.py -i "my srt subtitle.srt"

我很懒,并使用datetime模块来处理时间码,因此不确定脚本是否适用于24小时以后的字幕(:我也不确定在Python的datetime模块中添加了毫秒时,我使用的是2.7.5版本;由于这个原因,可能的脚本不适用于早期版本......