改變思路到底多重要?我通過這件小事兒明白了

我所說的一切都可能是錯的!
即使你贊同我的觀點,
你的生活也不會因此有任何改變!
除非——你採取了相應的行動。

(這是書先生的第226篇原創分享。2021年3月24日,於新加坡)

引子

今天分享一件小事兒。

事兒很小,之所以覺得值得分享,是因爲我從中學到了點兒重要的東西。

這個小事兒是這樣的:路夫人讓我幫忙處理個文檔。文檔長這樣:

其實就是《新概念英語第二冊》的中英對照版。夫人的要求是去掉所有的英文,但是每篇課文的標題要保留。

兩種思路

對我這種天天和語料庫打交道的人來說,這還不簡單,也就一行正則表達式的事兒。

正則表達式,英文叫regular expression,可以說是搞文本處理的朋友必須掌握的小技術。它的作用就是用一些符號的組合來匹配你想要搜索的字符串模式。你可以把它理解爲升級版的通配符。

比如“\d”表示所有的數字,“\w”表示所有的字母和漢字,“\t”表示製表符,等等等等。當然,更有用的是基本符號的合理組合,來匹配更加複雜的模式,比如:

匹配Email地址:\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*
匹配不定式(用於有句法標註的語料庫):to_TO\s.*?[a-zA-Z]+_V
匹配“it + BE + adj + that”結構(用於有詞性賦碼的語料庫):\S+_PPH1\s\S+_VB\w*\s\S+_J\w+\s\S+_CST\s
……

這個小技術在文本清理、爬蟲編寫和語料庫檢索方面很有用,對這些東西感興趣的朋友很有必要花點兒時間學一下。具體的技術細節不是本文的重點,我就不贅述了。

寫正則表達式的第一步就是觀察文本的特徵。我就在這一步犯了錯誤。

我的第一個思路是匹配有英文字母,但是不以“Lesson”開頭的句子,於是寫了這樣一個正則表達式:

^((?!Lesson)).*[a-zA-Z].*

這個表達式可以匹配所有包含英文字母但是不以Lesson開頭的行。一個比較簡單的表達式,稍微複雜點就是裏面對Lesson的“零寬負向先行斷言”((?!pattern))。

工作到此可以算是完成了,但我又看了看文本,發現自己犯了一個很傻的錯誤——我對文本的特徵概括有點複雜了。

的確,匹配所有包含英文但不以Lesson開頭的行,這個思路能完成任務。但是,根據文本的特徵,還有一個更簡單的思路,那就是匹配所有包含中文字符的行,因爲我們需要去掉的行一定是不含中文的。

這就是一個條件,而不是兩個條件了,從原理上來說,簡單了50%。於是我又寫了下面這個正則表達式:

.^((?![\u4e00-\u9fa5]).)$

其中[\u4e00-\u9fa5]是正則表達式裏匹配漢字的寫法。這個表達式能達到相同的效果。

粗一看,您可能覺得兩個表達式複雜程度差不多,而且都能達到目的。但是,從思路上來看,第二種更加簡潔和準確。

簡潔是因爲只需要判斷一個條件,準確是因爲需要去掉的行裏一定沒有英文字母,但需要保留的行裏卻可能出現英文字母。整個文本有幾十頁,我們不可能把全部文本都讀一遍纔來匹配,所以應該在編寫正則表達式時儘量選擇出錯概率小的。

結語

今天分享的的確是件小事兒,小到一分鐘就可以解決。但這處理這個小事兒時,思路的轉化,卻很值得思考。還是老規矩,我幫您總結一下。如果您經常會用正則表達式處理語料庫,下面兩點可能值得注意:

  1. 概括匹配對象特徵時,儘量減少匹配條件。
  2. 選擇表達式時,儘量選擇出錯概率小的。

好了,今天的分享就到這裏,希望對您有所幫助。歡迎點贊、留言、轉發,支持這個默默耕耘的靠譜公衆號。

(原創內容,未經允許,不得轉載!)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章