正則表達式的功法大全,做NLP再也不怕搞不定字元串了
選自Medium
作者:Jonny Fox
機器之心編譯
參與:思源
在自然語言處理中,很多時候我們都需要從文本或字元串中抽取出想要的信息,並進一步做語義理解或其它處理。在本文中,作者由基礎到高級介紹了很多正則表達式,這些表達式或規則在很多編程語言中都是通用的。
正則表達式(regex 或 regexp)對於從文本中抽取信息極其有用,它一般會搜索匹配特定模式的語句,而這種模式及具體的 ASCII 序列或 Unicode 字元。從解析/替代字元串、預處理數據到網頁爬取,正則表達式的應用範圍非常廣。
其中一個比較有意思的地方是,只要我們學會了正則表達式的語句,我們幾乎可以將其應用於多有的編程語言,包括 JavaScript、Python、Ruby 和 Java 等。只不過對於各編程語言所支持的最高級特徵與語法有細微的區別。
下面我們可以具體討論一些案例與解釋。
基本語句
錨點:^ 和 $
數量符:*、+、?和 {}
或運算符:| 、 []
字元類:d、d、s 和 .
使用「.」運算符需要非常小心,因為常見類或排除型字元類都要更快與精確。d、w 和s 同樣有它們各自的排除型字元類,即D、W 和S。例如D 將執行與d 完全相反的匹配方法:
為了正確地匹配,我們必須使用轉義符反斜杠「」定義我們需要匹配的符號「^.[$()|*+?{」,因為我們可能認為這些符號在原文本中有特殊的含義。
注意我們同樣能匹配 non-printable 字元,例如 Tab 符「 」、換行符「
」和回車符「
」
Flags
我們已經了解如何構建正則表達式,但仍然遺漏了一個非常基礎的概念:flags。
正則表達式通常以/abc/這種形式出現,其中搜索模式由兩個反斜杠「/」分離。而在模式的結尾,我們通常可以指定以下 flag 配置或它們的組合:
g(global)在第一次完成匹配後並不會返回結果,它會繼續搜索剩下的文本。
m(multi line)允許使用^和$匹配一行的開始和結尾,而不是整個序列。
i(insensitive)令整個表達式不區分大小寫(例如/aBc/i 將匹配 AbC)。
中級語句
分組和捕獲:()
捕獲性圓括弧 () 和非捕獲性圓括弧 (?:) 對於從字元串或數據中抽取信息非常重要,我們可以使用 Python 等不同的編程語言實現這一功能。從多個分組中捕獲的多個匹配項將以經典的數組形式展示:我們可以使用匹配結果的索引訪問它們的值。
如果需要為分組添加名稱(使用 (?...)),我們就能如字典那樣使用匹配結果檢索分組的值,其中字典的鍵為分組的名稱。
方括弧表達式:[]
記住在方括弧內,所有特殊字元(包括反斜杠)都會失去它們應有的意義。
Greedy 和 Lazy 匹配
數量符(* + {})是一種貪心運算符,所以它們會遍歷給定的文本,並儘可能匹配。例如, 可以匹配文本「This is a
simple div
test」中的「
simple div
」。為了僅捕獲 div 標籤,我們需要使用「?」令貪心搜索變得 Lazy 一點:
注意更好的解決方案應該需要避免使用「.」,這有利於實現更嚴格的正則表達式:
高級語句
邊界符: 和 B
如插入符號那樣表示一個錨點(它與$和^相同)來匹配位置,其中一邊是一個單詞符號(如w),另一邊不是單詞符號(例如它可能是字元串的起始點或空格符號)。
它同樣能表達相反的非單詞邊界「B」,它會匹配「」不會匹配的位置,如果我們希望找到被單詞字元環繞的搜索模式,就可以使用它。
前向匹配和後向匹配:(?=) 和 (?
我們同樣能使用否定運運算元:
結語
正如上文所示,正則表達式的應用領域非常廣,很可能各位讀者在開發的過程中已經遇到了它,下面是正則表達式常用的領域:
數據驗證,例如檢查時間字元串是否符合格式;
數據抓取,以特定順序抓取包含特定文本或內容的網頁;
數據包裝,將數據從某種原格式轉換為另外一種格式;
字元串解析,例如捕獲所擁有 URL 的 GET 參數,或捕獲一組圓括弧內的文本;
字元串替代,將字元串中的某個字元替換為其它字元。
本文為機器之心編譯,轉載請聯繫本公眾號獲得授權。
------------------------------------------------
※專欄 | 基於IR-transformer、IRGAN模型,解讀搜狗語義匹配技術
TAG:機器之心 |