split.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import re
  2. import difflib
  3. import math
  4. def sentence_time_ratio(text,maxLen):
  5. total_len = len(text)
  6. if total_len > maxLen:
  7. left_word = total_len % maxLen
  8. times = int(math.ceil(total_len/maxLen))
  9. if left_word < 3:
  10. times+=1
  11. sen_len = int(total_len/times)
  12. time_ratio = [None]*times
  13. sentences = [None]*times
  14. for t in range(times):
  15. sentences[t] = text[t*sen_len:t*sen_len+sen_len]
  16. time_ratio[t] = len(sentences[t])/total_len
  17. else:
  18. time_ratio = [1]
  19. sen_len = total_len
  20. sentences = [text]
  21. return sen_len, time_ratio, sentences
  22. #case : 1.短句mactch到很長的句子
  23. def parse_script(file_path,gt_list):
  24. with open(file_path, 'r',encoding="utf-8") as f:
  25. raw_lines = [line.strip() for line in f]
  26. lines = adjustSub_by_text_similarity(gt_list,raw_lines)
  27. dict_list = []
  28. for idx in range(int((len(lines)+1)/4)):
  29. script={}
  30. script['index'] = idx
  31. time_raw = raw_lines[idx * 4 +1 ]
  32. script['content'] = lines[idx*4+2]
  33. start = time_raw.split(' --> ')[0].split(':')
  34. stop = time_raw.split(' --> ')[1].split(':')
  35. start[2] = start[2].replace(',','.')
  36. stop[2] = stop[2].replace(',','.')
  37. start_sec = float(start[0])*3600 + float(start[1])*60 + float(start[2])
  38. stop_sec = float(stop[0])*3600 + float(stop[1])*60 + float(stop[2])
  39. duration = start_sec-stop_sec
  40. script['start'] = start_sec
  41. script['stop'] = stop_sec
  42. script['duration'] = abs(duration)
  43. dict_list.append(script)
  44. new_idx = 0
  45. splitted_dict = []
  46. for dic in dict_list:
  47. sen_len, time_ratio, sentences = sentence_time_ratio(dic['content'],13)
  48. for s in range(len(sentences)):
  49. new_dict = {}
  50. new_dict['index'] = new_idx
  51. start = dic['start']
  52. for t in range(s):
  53. start += (dic['duration']*time_ratio[t])
  54. new_dict['start'] = start
  55. new_dict['duration'] = dic['duration'] * time_ratio[s]
  56. new_dict['content'] = sentences[s]
  57. new_idx+=1
  58. splitted_dict.append(new_dict)
  59. return splitted_dict
  60. def adjustSub_by_text_similarity(gts,gens):
  61. adjusted = [None]*len(gens)
  62. combine2 = [''.join([i,j]) for i,j in zip(gts, gts[1:])]
  63. combine3 = [''.join([i,j,k]) for i,j,k in zip(gts, gts[1:], gts[2:])]
  64. alls = gts + combine2 + combine3
  65. for idx in range(len(gens)):
  66. match_text = difflib.get_close_matches(gens[idx], alls, cutoff=0.1)
  67. if len(match_text) != 0 and idx:
  68. adjusted[idx] = match_text[0]
  69. #1.is duplicated 2.is near
  70. if idx % 2 ==0:
  71. #print(gens[idx]+'||||校正後: '+match_text[0])
  72. print(match_text[0])
  73. return adjusted
  74. def trim_punctuation(s):
  75. pat_block = u'[^\u4e00-\u9fff0-9a-zA-Z]+';
  76. pattern = u'([0-9]+{0}[0-9]+)|{0}'.format(pat_block)
  77. res = re.sub(pattern, lambda x: x.group(1) if x.group(1) else u" " ,s)
  78. return res
  79. def splitter(s):
  80. for sent in re.findall(u'[^!?,。\!\?]+[!? 。\!\?]?', s, flags=re.U):
  81. yield sent
  82. def split_by_pun(s):
  83. res = list(splitter(s))
  84. return res
  85. def split_by_word(s):
  86. slice_size = 3
  87. paragraph_len = len(s)
  88. slice_num = int(math.ceil(paragraph_len/slice_size))
  89. slice_list = []
  90. for n in range(slice_num):
  91. slice_list.append(s[n*slice_size:n*slice_size+slice_size])
  92. return slice_list
  93. raw_str = '更糟糕的是,與大量關注相伴的並非用戶讚賞,而是 Windows 10 on ARM 的不成熟暴露無遺,以及隨之而來的如潮差評──對用戶使用體驗影響最惡劣的,莫過於 Windows 10 on ARM 僅能透過模擬兼容老舊過時的 32 位元 x86 應用,而對效能與普及度俱佳的 64 位元 x86(即 x64)應用無能為力'
  94. sub_dict = parse_script("out.txt",split_by_pun(raw_str))