Python3 如何優雅地使用Regex(詳解四)
來源:互聯網
上載者:User
更多強大的功能
到目前為止,我們只是介紹了Regex的一部分功能。在這一篇中,我們會學習到一些新的元字元,然後再教大家如何使用組來獲得被匹配的部分文本。
更多元字元
還有一些元字元我們沒有講到,接下來小甲魚一一為大家講解。
有些元字元它們不匹配任何字元,只是簡單地表示成功或失敗,因此這些字元也稱之為 零寬斷言 。例如 \b 表示當前位置位於一個單詞的邊界,但 \b 並不能改變位置。因此,零寬斷言不應該被重複使用,因為 \b 並不會修改當前位置,所以 \b\b 跟 \b 是沒什麼兩樣的。
小甲魚解釋:很多人可能不理解“改變位置”和“零寬斷言”的意思。我嘗試解釋下,比如 abc 匹配完 a 之後,咱的當前位置就會移動,才能繼續匹配 b,依次類推...但是 \babc 的話,\b 表示當前位置在單詞的邊界(單詞的第一個字母或者最後一個字母),這時候當前位置不會發生改變,接著將 a 與當前位置的字元進行匹配......
|
或操作符,對兩個Regex進行或操作。如果 A 和 B 是Regex, A | B 會匹配 A 或 B 中出現的任何字元。為了能夠更加合理的工作, | 的優先順序非常低。例如 Fish|C 應該匹配 Fish 或 C ,而不是匹配 Fis ,然後一個 'h' 或 'C' 。
同樣,我們使用 \| 來匹配 '|' 字元本身;或者包含在一個字元類中,像這樣 [|] 。
^
匹配字串的起始位置。如果設定了 MULTILINE 標誌,就會變成匹配每一行的起始位置。在 MULTILINE 中,每當遇到分行符號就會立刻進行匹配。
舉個例子,如果你只希望匹配位於字串開頭的單詞 From,那麼你的Regex可以寫為 ^From:
>>> print(re.search('^From', 'From Here to Eternity'))
< _sre.SRE_Match object; span=(0, 4), match='From'>
>>> print(re.search('^From', 'Reciting From Memory'))
None 複製代碼
$
匹配字串的結束位置,每當遇到分行符號也會離開進行匹配。
>>> print(re.search('}$', '{block}'))
<_sre.SRE_Match object; span=(6, 7), match='}'>
>>> print(re.search('}$', '{block} '))
None
>>> print(re.search('}$', '{block}\n'))
<_sre.SRE_Match object; span=(6, 7), match='}'>
同樣,我們使用 \$ 來匹配 '$' 字元本身;或者包含在一個字元類中,像這樣 [$] 。
\A
只匹配字串的起始位置。如果沒有設定 MULTILINE 標誌的時候, \A 和 ^ 的功能是一樣的;但如果設定了 MULTILINE 標誌,則會有一些不同: \A 還是匹配字串的起始位置,但 ^ 會對字串中的每一行都進行匹配。
\Z
只匹配字串的結束位置。
\b
單詞邊界,這是一個只匹配單詞的開始和結尾的零寬斷言。“單詞”定義為一個字母數位序列,所以單詞的結束指的是空格或者非字母數位字元。
下邊例子中, class 只有在出現一個完整的單詞 class 時才匹配;如果出現在別的單詞中,並不會匹配。 >>> p = re.compile(r'\bclass\b')
>>> print(p.search('no class at all'))
< _sre.SRE_Match object; span=(3, 8), match='class'>
>>> print(p.search('the declassified algorithm'))
None
>>> print(p.search('one subclass is'))
None 複製代碼
在使用這些特殊的序列的時候,有兩點是需要注意的:第一點需要注意的是,Python 的字串跟Regex在有些字元上是有衝突的(回憶之前反斜線的例子)。比如說在 Python 中, \b 表示的是退格符(ASCII 碼值是 8)。所以,你如果不使用原始字串,Python 會將 \b 轉換成退格符處理,這樣就肯定跟你的預期不一樣了。
下邊的例子中,我們故意不寫表示原始字串的 'r' ,結果確實大相庭徑:
>>> p = re.compile('\bclass\b')
>>> print(p.search('no class at all'))
None
>>> print(p.search('\b' + 'class' + '\b'))
< _sre.SRE_Match object; span=(0, 7), match='\x08class\x08'> 複製代碼
第二點需要注意的是,在字元類中不能使用這個斷言。跟 Python 一樣,在字元類中, \b 只是用來表示退格符。
\B
另一個零寬斷言,與 \b 的含義相反, \B 表示非單詞邊界的位置。
分組