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

2021-09-03 06:08:07 字數 4747 閱讀 6905

我們已經介紹完如何對字元進行搜尋,接下來我們講講正規表示式如何修改字串。

正規表示式使用以下方法修改字串:

方法用途

split()

在正規表示式匹配的地方進行分割,並返回乙個列表

sub()

找到所有匹配的子字串,並替換為新的內容

subn()

跟 sub() 幹一樣的勾當,但返回新的字串以及替換的數目

正規表示式的 split() 方法將字串在匹配的地方進行分割,並將分割後的結果作為列表返回。它的做法其實很像字串的 split() 方法,但這個可以使用更加廣泛的分隔符。你猜的沒錯,它同時提供了乙個模組級別的函式:re.split()

.split(string[, maxsplit=0])

通過正規表示式匹配來分割字串。如果在 re 中,你使用了捕獲組,那麼它們的內容會作為乙個列表返回。你可以通過傳入乙個 

maxsplit

引數來設定分割的數量。如果 

maxsplit

的值是非 0,表示至多有 

maxsplit

個分割會被處理,剩下的內容作為列表的最後乙個元素返回。

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

>>> p = re.compile(r'\w+')

>>> p.split('this is a test, short and sweet, of split().')

['this', 'is', 'a', 'test', 'short', 'and', 'sweet', 'of', 'split', '']

>>> p.split('this is a test, short and sweet, of split().', 3)

['this', 'is', 'a', 'test, short and sweet, of split().']

有時候你可能不僅對分隔符之間的內容感興趣,你可能對分隔符本身(就是正規表示式匹配的內容)也同樣感興趣。如果使用了捕獲組,那麼作為分隔符的值也會被返回:

>>> p = re.compile(r'\w+')

>>> p2 = re.compile(r'(\w+)')

>>> p.split('this... is a test.')

['this', 'is', 'a', 'test', '']

>>> p2.split('this... is a test.')

['this', '... ', 'is', ' ', 'a', ' ', 'test', '.', '']

模組級別的函式 re.split() 除了將 re 作為第乙個引數外,其他引數是一樣的:

>>> re.split('[\w]+', 'words, words, words.')

['words', 'words', 'words', '']

>>> re.split('([\w]+)', 'words, words, words.')

['words', ', ', 'words', ', ', 'words', '.', '']

>>> re.split('[\w]+', 'words, words, words.', 1)

['words', 'words, words.']

另乙個常見的任務就是找到所有的匹配部分,並替換成不同的字串。sub 方法可以幫你實現這個願望!sub 方法有乙個 

replacement

引數,它可以是乙個待替換的字串,或者乙個處理字串的函式。

.sub(replacement, string[, count=0])

返回乙個字串,這個字串從最左邊開始,所有 re 匹配的地方都替換成 

replacement

。如果沒有找到任何匹配,那麼返回原字串。

可選引數 

count

指定最多替換的次數,必須是乙個非負值。預設值是 0,意思是替換所有找到的匹配。

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

color

>>> p = re.compile( '(blue|white|red)')

>>> p.sub( 'colour', 'blue socks and red shoes')

'colour socks and colour shoes'

>>> p.sub( 'colour', 'blue socks and red shoes', count=1)

'colour socks and red shoes'

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

>>> p = re.compile( '(blue|white|red)')

>>> p.subn( 'colour', 'blue socks and red shoes')

('colour socks and colour shoes', 2)

>>> p.subn( 'colour', 'no colours at all')

('no colours at all', 0)

空匹配只有在它們沒有緊挨著前乙個匹配時才會被替換掉:

>>> p = re.compile('x*')

>>> p.sub('-', 'abxd')

'-a-b-d-'

如果 

replacement

引數是乙個字串,那麼裡邊的反斜槓都會被處理。比如

\n 將會被轉換成乙個換行符,

\r 轉換成回車,等等。未知的轉義如

\j 保持原樣。逆向引用如

\6,則被 re 中相應的捕獲組匹配的內容所替換。這使你可以在替換後的字串中插入一部分原字串。

下邊例子中,將匹配被

括起來的單詞

section

,並將 

section

替換成subsection

>>> p = re.compile('section]* ) }', re.verbose)

>>> p.sub(r'subsection','section section')

'subsection subsection'

解釋:

1. 大家還記得嗎?這裡開啟了 re.verbose,空格將被忽略。因為這裡一堆符號,用空格隔開看著才不會亂糟糟的......

2. 這裡

r'subsection' 

使用 \1 

引用匹配模式中的 

([^}]*) 

匹配的字串內容。

還可以使用 python 的擴充套件語法

(?p...) 

指定命名組,引用命名組的語法是\g。

\g會將名字為

name 

的組匹配的字串替換進去。另外,

\g《數字》 

是通過組的序號進行引用。

\g<2>

其實就相當於

\2,但我們更提倡使用

\g<2>

,因為這樣可以避免歧義。例如,

\g<2>0

的含義是引用序號為

2 的組,然後後邊匹配乙個字元

'0',而你寫成 

\20 

就會被認為是引用序號為

20 的組了。

>>> p = re.compile('section]* ) }', re.verbose)

>>> p.sub(r'subsection','section')

'subsection'

>>> p.sub(r'subsection','section')

'subsection'

>>> p.sub(r'subsection','section')

'subsection'

有時候你可能不滿足簡單的字串替換,你可能需要在替換的過程中動點「手腳」......沒關係,一樣可以滿足你!replacement 引數還可以是乙個函式,該函式將會在正規表示式模式每次不重複匹配的時候被呼叫。在每次呼叫時,函式會收到乙個匹配物件的引數,因此你就可以利用這個物件去計算出新的字串並返回它。

下邊的例子中,替換函式將十進位制數替換為十六進製制數:

>>> def hexrepl(match):

... "return the hex string for a decimal number"

... value = int(match.group())

... return hex(value)

...>>> p = re.compile(r'\d+')

>>> p.sub(hexrepl, 'call 65490 for printing, 49152 for user code.')

'call 0xffd2 for printing, 0xc000 for user code.'

當使用模組級的 re.sub() 函式時,正規表示式模式作為第乙個引數。該模式可以是乙個字串或乙個編譯好的物件。如果你需要指定正規表示式標誌,那麼你必須使用後者;或者使用模式內嵌修正器,例如 sub("(?i)b+", "x", "bbbb bbbb")返回 'x x'。

(未完待續)

Python3 如何優雅地使用正規表示式(詳解五)

非捕獲組命名組 精心設計的正規表示式可能會劃分很多組,這些組不僅可以匹配相關的子串,還能夠對正規表示式本身進行分組和結構化。在複雜的正規表示式中,由於有太多的組,因此通過組的序號來跟蹤和使用會變得困難。有兩個新的功能可以幫你解決這個問題 非捕獲組和命名組 它們都使用了乙個公共的正規表示式擴充套件語法...

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

修改字串 我們已經介紹完如何對字元進行搜尋,接下來我們講講正規表示式如何修改字串。正規表示式使用以下方法修改字串 方法用途 split 在正規表示式匹配的地方進行分割,並返回乙個列表 sub 找到所有匹配的子字串,並替換為新的內容 subn 跟 sub 幹一樣的勾當,但返回新的字串以及替換的數目 分...

Python3 如何優雅地使用正規表示式(詳解二)

現在我們開始來寫一些簡單的正規表示式吧。python 通過 re 模組為正規表示式引擎提供乙個介面,同時允許你將正規表示式編譯成模式物件,並用它們來進行匹配。解釋 re 模組是使用 c 語言編寫,所以效率比你用普通的字串方法要高得多 將正規表示式進行編譯 compile 也是為了進一步提高效率 後邊...