Python 正則表達式之四:re 模塊
最最基本的用法就是re.search了,在前面的三篇文章中,我們也已經見過多次,這里就不再贅述了。
re.sub
使用正則表達式進行查找替換,正是re.sub的功能。
例如,下面這個例子,將格式化列與之間逗號的用法:
>>> row = "column 1,column 2, column 3"
>>> re.sub(r',\s*', ',', row)
'column 1,column 2,column 3'
下面這個例子更復雜一些,配合正則表達式中的捕獲和引用特性,可以方便的轉換日期格式:
>>> sentence = "from 12/22/1629 to 11/14/1643"
>>> re.sub(r'(\d{2})/(\d{2})/(\d{4})', r'\3-\1-\2', sentence)
'from 1629-12-22 to 1643-11-14'
re.split
re.split,算是string.split的正則表達式增強版。
例如,對于如下的格式不太規范的逗號分隔的列,就可以用re.split分割出正確的列內容,比用re.findall簡潔得多:
>>> re.findall(r'([^,]*)(?:,\s*|$)', 'column1, column2,column3')
['column1', 'column2', 'column3', '']
>>> re.split(r',\s*', 'column1, column2,column3')
['column1', 'column2', 'column3']
re.compile
如果一個正則表達式會被多次用到,那么最好使用re.compile預先創建好一個正則對象,這樣執行效率更高。
>>> COMMA_RE = re.compile(r',\s*')
>>> COMMA_RE.split('column1, column2,column3')
['column1', 'column2', 'column3']
re.IGNORECASE和re.VERBOSE
re.IGNORECASE很簡單,就是在匹配的過程中忽略大小寫,就不單獨舉例了。
re.VERBOSE主要解決的是復雜的正則表達式可讀性差的問題。使用re.VERBOSE之后,正則表達式字符串中可以使用空格、換行等空白字符隔開各個子部分,增強可讀性。例如,如下的正則表達式,匹配了一個uuid字符串:
def is_valid_uuid(uuid):
hex_re = r'[ a-f \d ]'
uuid_re = r'''
^ # beginning of string
{hex} 8 # 8 hexadecimal digits
- # dash character
{hex} 4 # 4 hexadecimal digits
- # dash character
{hex} 4 # 4 hexadecimal digits
- # dash character
{hex} 4 # 4 hexadecimal digits
- # dash character
{hex} 12 # 12 hexadecimal digits
$ # end of string
'''.format(hex=hex_re)
uuid_regex = (uuid_re)
return bool(re.search(uuid_regex, uuid, re.IGNORECASE | re.VERBOSE))
這里用{ {8} }是因為format函數中對于{}有特殊含義(占位符),所以這需要轉義一次。
至此,對Python正則表達式的介紹就告一段落了。更多的細節,當然首推Python的官方文檔。
在使用正則表達式的過程中,經常會出現當時寫的爽,過后再看就犯迷糊的情況,這罪魁禍首就是可讀性差。雖然借助re.VERBOSE和注釋,可以部分緩解這一問題,但是依然不夠理想。
前一段時間閱讀skynet源碼,發現云風在解析skynet config文件時,用到了一個叫lpeg的lua庫來進行字符串的模式匹配。lpeg相比于裸正則表達式的優點在于,它可以將一個復雜的模式切分成若干個子部分,并且分別對其命名,然后像拼接字符串一樣對各個子模塊進行組合,可讀性很好。當然,已經有前輩幫我們將其移植到了Python中,有興趣的讀者可以點擊 這里 玩玩。
來自:http://blog.guoyb.com/2017/03/06/python-regex-4/