python正則表達式使用規範

       匹配字符串中的/**,對比以下三種用法。

import re

s = 'justfortesting/**csdopov**/python'

# 第一種方式
re.findall('/\\*\\*',s)
[out]: ['/**']

# 第二種方式
re.findall(r'/\*\*',s)
[out]: ['/**']

# 第三種方式
pattern = re.escape('/**')
re.findall(pattern,s)
[out]: ['/**']

       以上三種用法實際上是等價的,但是前兩者用法的正確使用的前提是正確的知道字符串轉義和正則轉義的知識,而第三種用法則直接使用正則表達式的re.escap(str)函數,這樣只要我們傳入想要匹配的str參數,該函數就可以返回正確的字符串轉義前和正則轉義前的字符串。這裏的str內容是我們想要匹配的字符串轉義前的字符串(即並非字面的,而是在字符串轉義語境下的),比如輸入str爲'\n',則是字符串轉義語境下的換行符,而不是字面的\和n。爲了更深入的瞭解escape函數的設計機制,我們看如下例子。

import re

# 第一種方式
pattern = re.escape('\n') # 這時如果在交互窗口下輸入pattern回車查看其內容,那麼顯示的是
                          # 轉義前(字符串轉義和正則轉義)字符串'\\\n'
re.findall(pattern,'\n')
[out]: ['\n']

# 第二種方式
re.findall('\\\n','\n')
[out]: ['\n']

# 第三種方式
re.findall('\\n','\n')
[out]: ['\n']

       以上三種方式中,第一種和第二種是等價的,因爲pattern實際上就是'\\\n',但是我們發現第三種方式也是可以匹配到換行符的。這是因爲正則語法的\n也表示換行符,即兼容字符串中的換行符。但是escape函數的設計是對於所有的字符串的,所以對於不兼容的字符,其也要保證正確性,因此如果str是特殊字符,那麼對於正則來說,需要在其前面加入轉義符\將其轉爲字符串意義下的字符,所以再回溯到字符串轉義,正則中\的成功加入需要在轉義前字符串中加入\\,因此對於特殊字符,escape函數都會在其前面多出兩個轉義符。更簡單一點的比如re.escape('*'),返回的就是'\\*'。

       綜上我們知道,對於正則表達式中的字符串轉義和正則轉義之間,是具有不太容易一下子搞清楚的關係的,所以如果不想理解這層關係,又保證正確的使用正則匹配,規範的用法是使用escape函數進行匹配字符到轉義前字符的轉化,然後再將得到的轉義前字符作爲參數傳給匹配函數。由於escape函數返回的是轉義前字符串,因此再將其結合原生字符串一起使用,是正則匹配最爲規範的用法,如下所示,compile函數中對於正則表達式使用原生字符串,並且字符串的格式化表達中傳入的字符串也是用escape函數返回的字符串,即轉義前字符串搭配轉義前字符串,這是最爲正確的組合,也是python正則匹配中最爲推薦的規範用法。

import re
 
def process(start,end,f):
 
    start = re.escape(start)
    end = re.escape(end)
    pattern = re.compile(r'%s(?:.|\s)*?%s'%(start,end))
 
    s = f.read()
    updated = ''.join(re.split(pattern,s))
 
    return updated

 

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