每一個英語學渣(好吧,其實這個說的就是學渣本渣了♀)都有這樣一個夢想:可以一邊輕鬆愉快地看着美劇,一邊本身的英語聽力水平還能蹭蹭地往上漲。知乎上也有不少人分享了本身經過美劇練習聽力的方法,好比說只開英文字幕或者乾脆就不要字幕。可是這兩個方法都有本身的缺點,只開英文字幕的方法雖說避免了下意識只看中文,可是卻形成了只看字幕不聽讀音,從而練習了閱讀忽略了聽力;不開字幕的方法確實作到了強迫本身必須認真聽,但是對於不少人來講,美劇中充滿了大量的陌生詞彙,好比說:python
這句話中的 betrayal 是背叛的名詞形式,可能不少人就不認識,或者說認識可是卻沒聽過他的正確發音。這樣一來,對這句話的理解就會出現障礙。美劇中還有不少相似狀況,用這樣的聽力材料顯然是不適合的。爲了應對這種狀況,我有了個想法:將字幕中的詞彙拆分,並進行詞頻的檢測,若是詞頻在 4000(能夠根據本身的狀況進行調整)之內,則將單詞刪除,若是詞頻在 4000 之外,則單獨標註出該詞的中文,效果以下:正則表達式
這樣一來,這句話對於我來講就沒有任何詞彙上的障礙,假如一遍聽不懂,我就能夠放心大膽的再聽一遍而沒必要擔憂是因爲詞彙的問題形成的理解障礙。數據庫
下面介紹程序的大致思路:編程
首先觀察字幕文件,選擇後綴名爲 srt 的字幕文件用記事本打開以下(其餘類型的字幕文件用記事本打開之後格式很是複雜,此處不討論):app
觀察文本特色,撰寫相應的正則表達式。函數
雖然在 Python 中使用正則表達式有幾個步驟,但每一步都至關簡單。學習
import re
導入正則表達式模塊。re.compile()
函數建立一個Regex
對象(記得使用原始字符串)。Regex
對象的search()
方法傳入想查找的字符串。它返回一個Match
對象。Match
對象的group()
方法,返回實際匹配文本的字符串。經常使用的匹配規則:spa
?
匹配零次或一次前面的分組。*
匹配零次或屢次前面的分組。+
匹配一次或屢次前面的分組。{n}
匹配 n 次前面的分組。{n,}
匹配 n 次或更多前面的分組。{,m}
匹配零次到 m 次前面的分組。{n,m}
匹配至少 n 次、至多 m 次前面的分組。{n,m}?
或*?
或+?
對前面的分組進行非貪心匹配。^spam
意味着字符串必須以 spam 開始。spam$
意味着字符串必須以 spam 結束。.
匹配全部字符,換行符除外。\d
、\w
和\s
分別匹配數字、單詞和空格。\D
、\W
和\S
分別匹配出數字、單詞和空格以外的全部字符。[abc]
匹配方括號內的任意字符(諸如 a、b 或 c)。[^abc]
匹配不在方括號內的任意字符Python中轉義字符使用倒斜槓(\
)。字符串'\n'
表示一個換行字符,而不是倒斜槓加上一個小寫的n。你須要輸入轉義字符\\
,才能打印出一個倒斜槓。因此'\\n'
表示一個倒斜槓加上一個小寫的 n。可是,經過在字符串的第一個引號以前加上r
,能夠將該字符串標記爲原始字符串,它不包括轉義字符。輸入r'\d\d\d-\d\d\d-\d\d\d\d'
,比輸入'\\d\\d\\d-\\d\\d\\d-\\d\\d\\d\\d'
要容易得多。翻譯
由上述相應規則結合文本特色獲得:3d
#空行、行數標號正則表達式
rgx_none_and_num = re.compile(r'\d{1,2}\n')
#時間正則表達式
rgx_time = re.compile(r'\d\d:\d\d:\d\d,\d\d\d --> \d\d:\d\d:\d\d,\d\d\d\n')
複製代碼
以後,由於要查詢詞頻,我在事先已經準備好了詞頻表:
要處理表格,須要用到 openpyxl 模塊,下面是從電子表格文件中讀取單元格涉及的全部函數、方法和數據類型。
openpyxl
模塊。openpyxl.load_workbook()
函數。Workbook
對象。get_active_sheet()
或get_sheet_by_name()
工做簿方法。Worksheet
對象。cell()
方法,帶上row
和column
關鍵字參數。Cell
對象。Cell
對象的value
屬性。由上述結合表格內容,創建詞庫字典:
#詞頻在4000之後的字典:
wordlist4001 = {}
#事先將名爲「1-20000.xlsx」的詞頻表放在當前工做目錄
excel_content = openpyxl.load_workbook('1-20000.xlsx')
sheet = excel_content['Sheet1']
for row in range(4000,20201):
wordlist4001[sheet.cell(row,1).value] = sheet.cell(row,2).value
#詞頻在4000之前的字典:
wordlist4000 = {}
for row in range(1,4001):
wordlist4000[sheet.cell(row,1).value] = sheet.cell(row,2).value
複製代碼
全部準備工做完成後,開始讀取字幕文件和處理字幕文件,最後新建一個處理事後的字幕文件。完整程序以下:
# -*- coding:utf-8 -*-
#導入模塊
import re,openpyxl
#讀入字幕文件
text=open('The.Big.Bang.Theory.s05e05.720p.x264.chs&eng.srt','r')
#空行、行數標號正則表達式
rgx_none_and_num = re.compile(r'\d{1,2}\n')
#時間正則表達式
rgx_time = re.compile(r'\d\d:\d\d:\d\d,\d\d\d --> \d\d:\d\d:\d\d,\d\d\d\n')
#處理字幕文件
first_step = text.readlines()
#新建一個字幕文件
new_file = open('C:\\Users\\SYQ\Desktop\\處理版.srt','w')
#創建4000後的字典
wordlist4001 = {}
excel_content = openpyxl.load_workbook('1-20000.xlsx')
sheet = excel_content['Sheet1']
for row in range(4000,20201):
wordlist4001[sheet.cell(row,1).value] = sheet.cell(row,2).value
#創建4000前的字典
wordlist4000 = {}
for row in range(1,4001):
wordlist4000[sheet.cell(row,1).value] = sheet.cell(row,2).value
#挑選出文字行進行處理
for line in first_step:
#若是爲空行,行數標號,則不動
if rgx_none_and_num.search(line):
new_file.write(line)
#若是爲時間行則不動
elif rgx_time.search(line):
new_file.write(line)
#若是爲字幕行,則處理
else:
words = line.lower().split()
for word in words:
#若是單詞不在字典中,則跳過
if word in wordlist4000:
pass
#若是單詞在字典中,則添加翻譯
elif word not in wordlist4001:
pass
else:
new_word = word + ':' + wordlist4001[word] +'\n'
new_file.write(new_word)
#關閉文件
text.close()
new_file.close()
複製代碼
由於我也是一個 python 初學者,所以在實現這個想法的過程當中也遇到了不少問題,最後實現的方法可能也顯得很笨拙,可是最後實現了仍是很開心的,哈哈哈。
----------
本文是咱們編程教室新春徵稿活動的一篇投稿,來自做者 @ 司夜。他和咱們不少讀者同樣,學習 python 的時間並不長,但已經把 python 應用到本身的平常學習生活中,並整理成文投稿給咱們,這很值得確定。 在實踐中應用和 向他人講解都是很是好的學習方式。不用在乎本身寫的代碼還不夠完善, Done is better than perfect!
咱們編程教室會持續向全部人開放,若是有投稿或參與志願者的意向,歡迎隨時在公衆號裏給咱們留言。
另外,關於編程與英語的結合,咱們以前也有過很多文章,感興趣的能夠閱讀:
Crossin:咱們用程序整理出了一份Python英語高頻詞彙表,拿走不謝!
分享一個強大的英漢詞典開源數據庫
英語 vs 編程
【每週一坑】單詞本(此係列可在公衆號「 每週一坑」欄目中查看)
════
其餘文章及回答:
學編程:如何自學Python | 新手引導 | 一圖學Python
歡迎搜索及關注:Crossin的編程教室