Python3 如何優雅地使用正則表達式(詳解六)

修改字符串

咱們已經介紹完如何對字符進行搜索,接下來咱們講講正則表達式如何修改字符串。

正則表達式使用如下方法修改字符串:

正則表達式

方法 用途
split() 在正則表達式匹配的地方進行分割,並返回一個列表
sub() 找到全部匹配的子字符串,並替換爲新的內容
subn() 跟 sub() 幹同樣的勾當,但返回新的字符串以及替換的數目



分割字符串

正則表達式的 split() 方法將字符串在匹配的地方進行分割,並將分割後的結果做爲列表返回。它的作法其實很像字符串的 split() 方法,但這個可使用更加普遍的分隔符。你猜的沒錯,它同時提供了一個模塊級別的函數:re.split()

.split(string[, maxsplit=0])函數

經過正則表達式匹配來分割字符串。若是在 RE 中,你使用了捕獲組,那麼它們的內容會做爲一個列表返回。你能夠經過傳入一個 maxsplit 參數來設置分割的數量。若是 maxsplit 的值是非 0,表示至多有 maxsplit 個分割會被處理,剩下的內容做爲列表的最後一個元素返回。spa


下邊例子中,分隔符是任何非字母數字字符:

code

  1. >>> p = re.compile(r'\W+')
  2. >>> p.split('This is a test, short and sweet, of split().')
  3. ['This', 'is', 'a', 'test', 'short', 'and', 'sweet', 'of', 'split', '']
  4. >>> p.split('This is a test, short and sweet, of split().', 3)
  5. ['This', 'is', 'a', 'test, short and sweet, of split().']
複製代碼


有時候你可能不只對分隔符之間的內容感興趣,你可能對分隔符自己(就是正則表達式匹配的內容)也一樣感興趣。若是使用了捕獲組,那麼做爲分隔符的值也會被返回:

對象

  1. >>> p = re.compile(r'\W+')
  2. >>> p2 = re.compile(r'(\W+)')
  3. >>> p.split('This... is a test.')
  4. ['This', 'is', 'a', 'test', '']
  5. >>> p2.split('This... is a test.')
  6. ['This', '... ', 'is', ' ', 'a', ' ', 'test', '.', '']
複製代碼


模塊級別的函數 re.split() 除了將 RE 做爲第一個參數外,其餘參數是同樣的:

ci

  1. >>> re.split('[\W]+', 'Words, words, words.')
  2. ['Words', 'words', 'words', '']
  3. >>> re.split('([\W]+)', 'Words, words, words.')
  4. ['Words', ', ', 'words', ', ', 'words', '.', '']
  5. >>> re.split('[\W]+', 'Words, words, words.', 1)
  6. ['Words', 'words, words.']
複製代碼



搜索和替換

另外一個常見的任務就是找到全部的匹配部分,並替換成不一樣的字符串。sub 方法能夠幫你實現這個願望!sub 方法有一個replacement 參數,它能夠是一個待替換的字符串,或者一個處理字符串的函數。

.sub(replacementstring[, count=0])字符串

返回一個字符串,這個字符串從最左邊開始,全部 RE 匹配的地方都替換成 replacement。若是沒有找到任何匹配,那麼返回原字符串。string

可選參數 count 指定最多替換的次數,必須是一個非負值。默認值是 0,意思是替換全部找到的匹配。it


下邊是使用 sub() 方法的例子,它會將全部的顏色替換成 color

io

  1. >>> p = re.compile( '(blue|white|red)')
  2. >>> p.sub( 'colour', 'blue socks and red shoes')
  3. 'colour socks and colour shoes'
  4. >>> p.sub( 'colour', 'blue socks and red shoes', count=1)
  5. 'colour socks and red shoes'
複製代碼


subn() 方法跟 sub() 方法幹一樣的勾當,但區別是返回值爲一個包含有兩個元素的元組:一個是替換後的字符串,一個是替換的數目。

  1. >>> p = re.compile( '(blue|white|red)')
  2. >>> p.subn( 'colour', 'blue socks and red shoes')
  3. ('colour socks and colour shoes', 2)
  4. >>> p.subn( 'colour', 'no colours at all')
  5. ('no colours at all', 0)
複製代碼


空匹配只有在它們沒有緊挨着前一個匹配時纔會被替換掉:

  1. >>> p = re.compile('x*')
  2. >>> p.sub('-', 'abxd')
  3. '-a-b-d-'
複製代碼


若是 replacement 參數是一個字符串,那麼裏邊的反斜槓都會被處理。好比 \n 將會被轉換成一個換行符,\r 轉換成回車,等等。未知的轉義如 \j 保持原樣。逆向引用如 \6,則被 RE 中相應的捕獲組匹配的內容所替換。這使你能夠在替換後的字符串中插入一部分原字符串。

下邊例子中,將匹配被 { 和 } 括起來的單詞 section,並將 section 替換成 subsection

  1. >>> p = re.compile('section{ ( [^}]* ) }', re.VERBOSE)
  2. >>> p.sub(r'subsection{\1}','section{First} section{second}')
  3. 'subsection{First} subsection{second}'
複製代碼


小甲魚解釋:1. 你們還記得嗎?這裏開啓了 re.VERBOSE,空格將被忽略。由於這裏一堆符號,用空格隔開看着纔不會亂糟糟的......2. 這裏 r'subsection{\1}' 使用 \1 引用匹配模式中的 ([^}]*) 匹配的字符串內容。

還可使用 Python 的擴展語法 (?P<name>...) 指定命名組,引用命名組的語法是 \g<name>\g<name> 會將名字爲name 的組匹配的字符串替換進去。另外,\g<數字> 是經過組的序號進行引用。\g<2> 其實就至關於 \2,但咱們更提倡使用 \g<2>,由於這樣能夠避免歧義。例如,\g<2>0 的含義是引用序號爲 2 的組,而後後邊匹配一個字符 '0',而你寫成\20 就會被認爲是引用序號爲 20 的組了。

  1. >>> p = re.compile('section{ (?P<name> [^}]* ) }', re.VERBOSE)
  2. >>> p.sub(r'subsection{\1}','section{First}')
  3. 'subsection{First}'
  4. >>> p.sub(r'subsection{\g<1>}','section{First}')
  5. 'subsection{First}'
  6. >>> p.sub(r'subsection{\g<name>}','section{First}')
  7. 'subsection{First}'
複製代碼


有時候你可能不知足簡單的字符串替換,你可能須要在替換的過程當中動點「手腳」......不要緊,同樣能夠知足你!replacement 參數還能夠是一個函數,該函數將會在正則表達式模式每次不重複匹配的時候被調用。在每次調用時,函數會收到一個匹配對象的參數,所以你就能夠利用這個對象去計算出新的字符串並返回它。

下邊的例子中,替換函數將十進制數替換爲十六進制數:

  1. >>> def hexrepl(match):
  2. ...     "Return the hex string for a decimal number"
  3. ...     value = int(match.group())
  4. ...     return hex(value)
  5. ...
  6. >>> p = re.compile(r'\d+')
  7. >>> p.sub(hexrepl, 'Call 65490 for printing, 49152 for user code.')
  8. 'Call 0xffd2 for printing, 0xc000 for user code.'
複製代碼


當使用模塊級的 re.sub() 函數時,正則表達式模式做爲第一個參數。該模式能夠是一個字符串或一個編譯好的對象。若是你須要指定正則表達式標誌,那麼你必須使用後者;或者使用模式內嵌修正器,例如 sub("(?i)b+", "x", "bbbb BBBB") 返回 'x x'

相關文章
相關標籤/搜索