引子:關于正則表達式……
正則表達式這個名字看起來總有點古怪,概念似乎也不簡單,甚至需要用一整本書來講解。可是,它到底是什么呢?
同為技術人員,我相信你總會與字符串打交道,相應的,各種語言也都提供了與字符串有關的函數。我們先看下面幾個問題,用字符串函數是如何解決的(下面的代碼使用Python語言,它很直觀,正文里有基礎的介紹。現在,你只需要知道def是定義函數的關鍵詞即可)。
引入正則表達式
1.判斷字符ch是否是數字字符

2.判斷字符串str是否是電話號碼(為簡單起見,現在只考慮固定電話號碼,也就是長度在7~8位之間的數字字符串,且第一位不為0)

任務的復雜度并沒有增加太多,程序的復雜度增加了很多倍;如果你不同意,那么,來一個更復雜的。
3.找出一段文本中所有的電話號碼
最直接的辦法是,在字符串中的每個位置截取7~8個字符,調用之前的isPhoneNum()。這么做看起來沒問題,只是效率太低。
當然,做點改進也不難,加上一個前置條件,只在“當前字符為數字字符”的情況下調用isPhoneNum()。這樣效率倒是改進了,但是還有問題沒有解決:要求找到的是長度大于等于7個字符、小于等于8個字符的“數字字符串”,而不是“子字符串”—也就是說,假如數字字符串是64240000,需要將它找出來;如果數字字符串是13800138000,則需要忽略它,以及其中的任何子串(比如13800138、00138000)。
所以,用isPhoneNum()找出字符串之后,還需要保證它之前的字符不是數字字符,之后的字符也不是數字字符。看起來很簡單,但合格的程序員一定要考慮邊界問題,避免越界錯誤:如果當前字符是整段文本的第一個字符,則不需要判斷之前的字符,因為它不存在;同樣,如果找出的字符串在整段文本的末尾,則不需要判斷之后的字符,因為它同樣不存在……
到現在為止,即便只是找到最簡單的固定電話號碼,程序也非常復雜,難以維護。如果要查找的是形式更多變的文本,比如帶區號的電話號碼(021-64240000或者03718888888)、手機號碼(13800138000、+8613800138000或者013800138000),程序更是不可想象,更不用說文件路徑名、URL地址、電子郵件地址了!然而,日常開發中我們又確實經常需要面對這類任務,有什么更好的辦法呢?
正則表達式就是解決這類問題的萬能藥。雖然許多人有點看不起它,覺得不入流,一些科班教材里也不會花太多篇幅來介紹它,但它確實是解決問題的利器——之前提到的三個例子,用正則表達式都可以輕松解決。
引入正則表達式之后
1.判斷字符ch是否是數字字符

看起來很復雜,其實并不復雜:這里真正要關心的就是正則表達式[0-9],它表示“從0到9之間的任意字符”,很形象吧?re.search()是正則表達式運算函數,它判斷ch能否由正則表達式[0-9]匹配,可以則返回一個結果,否則返回None(這些細節正文中會講到)。
2.判斷字符串str是否是電話號碼

這個正則表達式最開始是[1-9],表示第一個字符必須是1~9之間的數字字符;之后是[0-9]{6,7},表示長度在6和7之間,由0~9之間的數字字符組成的字符串(兩部分加起來,整個字符串的長度在7和8之間)。要解決的問題復雜了,正則表達式仍然直觀形象。
3.找出一段文本中所有的固定電話號碼

這個正則表達式之前多出了(?<![0-9]),表示“之前不能是[0-9]”;之后多出了(?![0-9]),表示“之后不能是[0-9]”。雖然稍微復雜點,但意思明確,而且不難理解。re.findall()的意思也很明顯:找到所有這樣的字符串。
可以想象,循著這種思路,查找更復雜的電話號碼、手機號碼等任務都不難解決。更重要的是,之前需要許多行語句才能完成的任務,現在基本上只需要一個正則表達式、一條語句就可以完成。正因為如此,不少人雖然認為正則表達式不夠花哨、漂亮,卻不得不承認它是一種“匕首應用”—匕首,沒有十八般兵刃那么氣派,關鍵時候卻不可或缺,所以值得花時間練練。同樣,正則表達式雖然不能用來顯擺,但總有派得上用場的地方,花時間練練絕不是壞事。即便你的工作不是純粹的文本處理(比如日志分析),也總會有用到正則表達式的地方(比如查找和修改源代碼),所以我希望,這本書能陪伴你練出一身正則表達式的好功夫,在關鍵場合能亮出稱手的工具。
最后,為了傳承經典教科書的良好習慣,附上正則表達式的“科班史”。
正則表達式發源于與計算機密切相關的兩個領域:計算理論和形式語言。20世紀40年代,兩位神經生理學家Warren McCulloch和Walter Pitts發明了一種用數學方式來描述神經網絡的辦法,他們把神經系統中的神經元描述成小而簡單的自動控制單元。1956年,數學家Stephen Cole Kleene在他們研究的基礎上,發表了一篇名為《神經網事件的表示法》的論文,在其中,他采用了一些稱之為“正則集合(regular set)”的數學符號來描述神經網絡模型。
之后,UNIX的主要發明人Ken Thompson將這個符號系統引入了文本編輯器QED(意思是“在文本中搜索某種模式”),正則表達式由此也進入了計算機世界。隨后Ken Thompson又將正則表達式引入了UNIX下的文本編輯器ed,ed最終演化為大家熟悉的grep(grep得名自ed編輯器中的正則表達式搜索命令g/re/p,其中的re表示“正則表達式”)。
- Vue 3移動Web開發與性能調優實戰
- Mastering JavaScript Object-Oriented Programming
- PostgreSQL技術內幕:事務處理深度探索
- Java持續交付
- Linux Device Drivers Development
- Unreal Engine 4 Shaders and Effects Cookbook
- Working with Odoo
- Python算法指南:程序員經典算法分析與實現
- Learning R for Geospatial Analysis
- Creating Data Stories with Tableau Public
- Raspberry Pi Robotic Projects(Third Edition)
- 監控的藝術:云原生時代的監控框架
- PHP項目開發全程實錄(第4版)
- 深入理解Kafka:核心設計與實踐原理
- R語言實戰(第2版)