首頁 > 軟體

Python中re模組的元字元使用小結

2022-04-07 13:01:30

元字元(Meta Characters)是正規表示式中具有特殊意義的專用字元,在Python中也不例外,是用來指明前導字元(位於元字元前的字元)在目標物件中的出現模式。

在正規表示式中,方括號 ( [] ) 中指定的一組字元組成一個字元類。

# 元字元序列匹配類中的任何單個字元
>>> s = 'foo123bar'

# 3個任意連續字元匹配
>>> re.search('[0-9][0-9][0-9]', s)
<_sre.SRE_Match object; span=(3, 6), match='123'>

>>> re.search('[0-9][0-9][0-9]', 'foo456bar')
<_sre.SRE_Match object; span=(3, 6), match='456'>

>>> re.search('[0-9][0-9][0-9]', '234baz')
<_sre.SRE_Match object; span=(0, 3), match='234'>

>>> re.search('[0-9][0-9][0-9]', 'qux678')
<_sre.SRE_Match object; span=(3, 6), match='678'>

# 匹配不上的情況
>>> print(re.search('[0-9][0-9][0-9]', '12foo34'))
None

萬用字元點 ( . ) 元字元匹配除換行符以外的任何字元。

>>> s = 'foo123bar'
>>> re.search('1.3', s)
<_sre.SRE_Match object; span=(3, 6), match='123'>

>>> s = 'foo13bar'
>>> print(re.search('1.3', s))
None

re模組支援的元字元

下面列表都是元字元的描述,對元字元進行分類描述方便記憶。 這個要是看不懂直接看跳過看下面的例子。

字元描述
將下一個字元標記為一個特殊字元、或一個原義字元、或一個 向後參照、或一個八進位制跳脫符。例如,‘n’ 匹配字元 “n”。‘n’ 匹配一個換行符。序列 ‘’ 匹配 “” 而 “(” 則匹配 “(”。
^匹配輸入字串的開始位置。如果設定了 RegExp 物件的 Multiline 屬性,^ 也匹配 ‘n’ 或 ‘r’ 之後的位置。
$匹配輸入字串的結束位置。如果設定了RegExp 物件的 Multiline 屬性,$ 也匹配 ‘n’ 或 ‘r’ 之前的位置。
*匹配前面的子表示式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等價於{0,}。
+匹配前面的子表示式一次或多次。例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等價於 {1,}。
?匹配前面的子表示式零次或一次。例如,“do(es)?” 可以匹配 “do” 或 “does” 。? 等價於 {0,1}。
{n}n 是一個非負整數。匹配確定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的兩個 o。
{n,}n 是一個非負整數。至少匹配n 次。例如,‘o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。‘o{1,}’ 等價於 ‘o+’。‘o{0,}’ 則等價於 ‘o*’。
{n,m}m 和 n 均為非負整數,其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,“o{1,3}” 將匹配 “fooooood” 中的前三個 o。‘o{0,1}’ 等價於 ‘o?’。請注意在逗號和兩個數之間不能有空格。
?當該字元緊跟在任何一個其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 後面時,匹配模式是非貪婪的。非貪婪模式儘可能少的匹配所搜尋的字串,而預設的貪婪模式則儘可能多的匹配所搜尋的字串。例如,對於字串 “oooo”,‘o+?’ 將匹配單個 “o”,而 ‘o+’ 將匹配所有 ‘o’。
.匹配除換行符(n、r)之外的任何單個字元。要匹配包括 ‘n’ 在內的任何字元,請使用像"(.
x|y匹配 x 或 y。例如,'z
[xyz]字元集合。匹配所包含的任意一個字元。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。
[^xyz]負值字元集合。匹配未包含的任意字元。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p’、‘l’、‘i’、‘n’。
[a-z]字元範圍。匹配指定範圍內的任意字元。例如,‘[a-z]’ 可以匹配 ‘a’ 到 ‘z’ 範圍內的任意小寫字母字元。
[^a-z]負值字元範圍。匹配任何不在指定範圍內的任意字元。例如,‘[^a-z]’ 可以匹配任何不在 ‘a’ 到 ‘z’ 範圍內的任意字元。
b匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, ‘erb’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。
B匹配非單詞邊界。‘erB’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。
cx匹配由 x 指明的控制字元。例如, cM 匹配一個 Control-M 或回車符。x 的值必須為 A-Z 或 a-z 之一。否則,將 c 視為一個原義的 ‘c’ 字元。
d匹配一個數位字元。等價於 [0-9]。
D匹配一個非數位字元。等價於 [^0-9]。
f匹配一個換頁符。等價於 x0c 和 cL。
n匹配一個換行符。等價於 x0a 和 cJ。
r匹配一個回車符。等價於 x0d 和 cM。
s匹配任何空白字元,包括空格、製表符、換頁符等等。等價於 [ fnrtv]。
S匹配任何非空白字元。等價於 [^ fnrtv]。
t匹配一個製表符。等價於 x09 和 cI。
v匹配一個垂直製表符。等價於 x0b 和 cK。
w匹配字母、數位、下劃線。等價於’[A-Za-z0-9_]'。
W匹配非字母、數位、下劃線。等價於 ‘[^A-Za-z0-9_]’。
xn匹配 n,其中 n 為十六進位制跳脫值。十六進位制跳脫值必須為確定的兩個數位長。例如,‘x41’ 匹配 “A”。‘x041’ 則等價於 ‘x04’ & “1”。正規表示式中可以使用 ASCII 編碼。
num匹配 num,其中 num 是一個正整數。對所獲取的匹配的參照。例如,‘(.)1’ 匹配兩個連續的相同字元。
n標識一個八進位制跳脫值或一個向後參照。如果 n 之前至少 n 個獲取的子表示式,則 n 為向後參照。否則,如果 n 為八進位制數位 (0-7),則 n 為一個八進位制跳脫值。
nm標識一個八進位制跳脫值或一個向後參照。如果 nm 之前至少有 nm 個獲得子表示式,則 nm 為向後參照。如果 nm 之前至少有 n 個獲取,則 n 為一個後跟文字 m 的向後參照。如果前面的條件都不滿足,若 n 和 m 均為八進位制數位 (0-7),則 nm 將匹配八進位制跳脫值 nm。
nml如果 n 為八進位制數位 (0-3),且 m 和 l 均為八進位制數位 (0-7),則匹配八進位制跳脫值 nml。
un匹配 n,其中 n 是一個用四個十六進位制數位表示的 Unicode 字元。例如, u00A9 匹配版權符號 (?)。

類別1:匹配單個字元的元字元

方括號( [] ) 字元集

指定要匹配的特定字元集。 字元類元字元序列將匹配該類中包含的任何單個字元。

# 元字元序列[artz]匹配任何單個'a'、'r'、't'或'z'字元
# ba[artz]同時匹配'bar'and 'baz'(也將匹配'baa'and 'bat')。
>>> re.search('ba[artz]', 'foobarqux')
<_sre.SRE_Match object; span=(3, 6), match='bar'>
>>> re.search('ba[artz]', 'foobazqux')
<_sre.SRE_Match object; span=(3, 6), match='baz'>

匹配和[a-z]之間的任何小寫字母字元。

>>> re.search('[a-z]', 'FOObar')
<_sre.SRE_Match object; span=(3, 4), match='b'>

匹配和[0-9]之間任何數位字元。

>>> re.search('[0-9][0-9]', 'foo123bar')
<_sre.SRE_Match object; span=(3, 5), match='12'>

[0-9a-fA-F]匹配任何十六進位制數位字元。

>>> re.search('[0-9a-fA-f]', '--- a0 ---')
<_sre.SRE_Match object; span=(4, 5), match='a'>

[^0-9]匹配任何不是數位的字元開頭的字元。

>>> re.search('[^0-9]', '12345foo')
<_sre.SRE_Match object; span=(5, 6), match='f'>

如果一個^字元出現在字元類中但不是第一個字元則無結果。

>>> re.search('[#:^]', 'foo^bar:baz#qux')
<_sre.SRE_Match object; span=(3, 4), match='^'>

可以通過用連字元分隔字元來指定字元類中的字元範圍,可以將其作為第一個或最後一個字元放置,或者使用反斜槓 ( ) 對其進行跳脫。

# 直接查詢符號
>>> re.search('[-abc]', '123-456')
<_sre.SRE_Match object; span=(3, 4), match='-'>
>>> re.search('[abc-]', '123-456')
<_sre.SRE_Match object; span=(3, 4), match='-'>
>>> re.search('[ab-c]', '123-456')
<_sre.SRE_Match object; span=(3, 4), match='-'>


# 查詢跳脫符號
>>> re.search('[]]', 'foo[1]')
<_sre.SRE_Match object; span=(5, 6), match=']'>
>>> re.search('[ab]cd]', 'foo[1]')
<_sre.SRE_Match object; span=(5, 6), match=']'>


# [ ] 內的元字元失去意義跳脫成字元處理
>>> re.search('[)*+|]', '123*456')
<_sre.SRE_Match object; span=(3, 4), match='*'>
>>> re.search('[)*+|]', '123+456')
<_sre.SRE_Match object; span=(3, 4), match='+'>

點 ( . ) 萬用字元

匹配除換行符以外的任何單個字元。

>>> re.search('foo.bar', 'fooxbar')
<_sre.SRE_Match object; span=(0, 7), match='fooxbar'>
>>> print(re.search('foo.bar', 'foobar'))
None
>>> print(re.search('foo.bar', 'foonbar'))
None
>>> print(re.search('foo.bar', 'foosbar'))
<_sre.SRE_Match object; span=(0, 7), match='foosbar'>

w 和 W 單詞字元匹配

w匹配任何字母數位字元,單詞字元是大寫和小寫字母、數位和下劃線 ( _) 字元。

w 等於 [a-zA-Z0-9_] 。

>>> re.search('w', '#(.a$@&')
<_sre.SRE_Match object; span=(3, 4), match='a'>
>>> re.search('[a-zA-Z0-9_]', '#(.a$@&')
<_sre.SRE_Match object; span=(3, 4), match='a'>

W是相反的。它匹配任何非單詞字元。

W 等於 [^a-zA-Z0-9_] 。

>>> re.search('W', 'a_1*3Qb')
<_sre.SRE_Match object; span=(3, 4), match='*'>
>>> re.search('[^a-zA-Z0-9_]', 'a_1*3Qb')
<_sre.SRE_Match object; span=(3, 4), match='*'>

d 和 D 字元十進位制數位匹配

d匹配任何十進位制數位字元,等價於[0-9]。

>>> re.search('d', 'abc4def')
<_sre.SRE_Match object; span=(3, 4), match='4'>

D匹配任何不是十進位制數位的字元,等價於[^0-9]。

>>> re.search('D', '234Q678')
<_sre.SRE_Match object; span=(3, 4), match='Q'>

s 和 S 字元空格匹配

s匹配任何空白字元,同時也匹配換行符。

>>> re.search('s', 'foonbar baz')
<_sre.SRE_Match object; span=(3, 4), match='n'>

S匹配任何不是空格的字元。

>>> re.search('S', '  n foo  n  ')
<_sre.SRE_Match object; span=(4, 5), match='f'>

混合使用 w, W, d, D, s, 和S

字元類序列w, W, d, D, s, 和S也可以出現在方括號字元類中。

# [dws]匹配任何數位、單詞或空白字元

>>> re.search('[dws]', '---3---')
<_sre.SRE_Match object; span=(3, 4), match='3'>
>>> re.search('[dws]', '---a---')
<_sre.SRE_Match object; span=(3, 4), match='a'>
>>> re.search('[dws]', '--- ---')
<_sre.SRE_Match object; span=(3, 4), match=' '>

# 由於w包含d,相同的字元類也可以表示為略短[ws]
>>> re.search('[ws]', '---a---')
<_sre.SRE_Match object; span=(3, 4), match='a'>
>>> re.search('[ws]', '---a---')
<_sre.SRE_Match object; span=(3, 4), match='a'>
>>> re.search('[ws]', '--- ---')
<_sre.SRE_Match object; span=(3, 4), match=' '>

類別2:跳脫元字元

反斜槓 ( ) 跳脫元字元

反斜槓會刪除元字元的特殊含義。

>>> re.search('.', 'foo.bar')
<_sre.SRE_Match object; span=(0, 1), match='f'>

>>> re.search('.', 'foo.bar') # 非萬用字元
<_sre.SRE_Match object; span=(3, 4), match='.'>

>>> re.search(r'\', 'foobar')
<_sre.SRE_Match object; span=(3, 4), match='\'>

類別3:錨點

不匹配搜尋字串中的任何實際字元,並且在解析期間它們不使用任何搜尋字串。指示搜尋字串中必須發生匹配的特定位置。

^ 和 A 字串的開頭匹配項

>>> re.search('^foo', 'foobar')
<_sre.SRE_Match object; span=(0, 3), match='foo'>
>>> print(re.search('^foo', 'barfoo'))
None

>>> re.search('Afoo', 'foobar')
<_sre.SRE_Match object; span=(0, 3), match='foo'>
>>> print(re.search('Afoo', 'barfoo'))
None

$ 和Z 字串的結尾匹配項

>>> re.search('bar$', 'foobar')
<_sre.SRE_Match object; span=(3, 6), match='bar'>
>>> print(re.search('bar$', 'barfoo'))
None

>>> re.search('barZ', 'foobar')
<_sre.SRE_Match object; span=(3, 6), match='bar'>
>>> print(re.search('barZ', 'barfoo'))
None

# 特殊$也在搜尋字串末尾的單個換行符之前匹配
>>> re.search('bar$', 'foobarn')
<_sre.SRE_Match object; span=(3, 6), match='bar'>

b 和 B 單詞匹配

b 必須在單詞的開頭或結尾。

# 單詞開頭
>>> re.search(r'bbar', 'foo bar')
<_sre.SRE_Match object; span=(4, 7), match='bar'>
>>> re.search(r'bbar', 'foo.bar')
<_sre.SRE_Match object; span=(4, 7), match='bar'>
>>> print(re.search(r'bbar', 'foobar'))
None

# 單詞結尾
>>> re.search(r'foob', 'foo bar')
<_sre.SRE_Match object; span=(0, 3), match='foo'>
>>> re.search(r'foob', 'foo.bar')
<_sre.SRE_Match object; span=(0, 3), match='foo'>
>>> print(re.search(r'foob', 'foobar'))
None


# 單詞居中
>>> re.search(r'bbarb', 'foo bar baz')
<_sre.SRE_Match object; span=(4, 7), match='bar'>
>>> re.search(r'bbarb', 'foo(bar)baz')
<_sre.SRE_Match object; span=(4, 7), match='bar'>
>>> print(re.search(r'bbarb', 'foobarbaz'))
None

B 不能在單詞的開頭或結尾。

>>> print(re.search(r'BfooB', 'foo'))
None
>>> print(re.search(r'BfooB', '.foo.'))
None
>>> re.search(r'BfooB', 'barfoobaz')
<_sre.SRE_Match object; span=(3, 6), match='foo'>

類別4:量詞

該部分必須出現多少次才能使匹配成功。

* 匹配前面的子表示式零次或多次

>>> re.search('foo-*bar', 'foobar')                 
<_sre.SRE_Match object; span=(0, 6), match='foobar'>
>>> re.search('foo-*bar', 'foo-bar')                   
<_sre.SRE_Match object; span=(0, 7), match='foo-bar'>
>>> re.search('foo-*bar', 'foo--bar')                
<_sre.SRE_Match object; span=(0, 8), match='foo--bar'>

匹配2個字元中全部的內容。

>>> re.search('foo.*bar', '# foo jklasajk#*(@ bar #')
<_sre.SRE_Match object; span=(2, 22), match='foo jklasajk#*(@ bar'>

+ 匹配前面的子表示式一次或多次

>>> print(re.search('foo-+bar', 'foobar'))              
None
>>> re.search('foo-+bar', 'foo-bar')                   
<_sre.SRE_Match object; span=(0, 7), match='foo-bar'>
>>> re.search('foo-+bar', 'foo--bar')                  
<_sre.SRE_Match object; span=(0, 8), match='foo--bar'>

? 匹配前面的子表示式零次或一次

>>> re.search('foo-?bar', 'foobar')                    
<_sre.SRE_Match object; span=(0, 6), match='foobar'>
>>> re.search('foo-?bar', 'foo-bar')                   
<_sre.SRE_Match object; span=(0, 7), match='foo-bar'>
>>> print(re.search('foo-?bar', 'foo--bar'))           
None

.*?、+?、?? 最小長度匹配

加問號則表示為最小長度匹配的懶惰模式。

### + 和 +? 代替了 * 和 *?

# .*全匹配貪婪模式
>>> re.search('<.*>', '%<foo> <bar> <baz>%')
<_sre.SRE_Match object; span=(1, 18), match='<foo> <bar> <baz>'>
# *? 前一個字元0次或無限次擴充套件,最小匹配
>>> re.search('<.*?>', '%<foo> <bar> <baz>%')
<_sre.SRE_Match object; span=(1, 6), match='<foo>'>
# .+ 前一個字元1次或無限次擴充套件,最小匹配
>>> re.search('<.+>', '%<foo> <bar> <baz>%')
<_sre.SRE_Match object; span=(1, 18), match='<foo> <bar> <baz>'>
# .+? 前一個字元1次或無限次擴充套件,最小匹配
>>> re.search('<.+?>', '%<foo> <bar> <baz>%')
<_sre.SRE_Match object; span=(1, 6), match='<foo>'>

# ? 匹配懶惰模式
>>> re.search('ba?', 'baaaa')
<_sre.SRE_Match object; span=(0, 2), match='ba'>
# ?? 前一個字元0次或1次擴充套件,最小匹配
>>> re.search('ba??', 'baaaa')
<_sre.SRE_Match object; span=(0, 1), match='b'>

{m} 完全匹配m次前面元字元的正規表示式。

>>> print(re.search('x-{3}x', 'x--x'))                
None
>>> re.search('x-{3}x', 'x---x')                     
<_sre.SRE_Match object; span=(0, 5), match='x---x'>
>>> print(re.search('x-{3}x', 'x----x'))             
None

{m,n} 匹配前面正規表示式的任意數量的重複從m到n次

>>> for i in range(1, 6):
...     s = f"x{'-' * i}x"
...     print(f'{i}  {s:10}', re.search('x-{2,4}x', s))
...
1  x-x        None
2  x--x       <_sre.SRE_Match object; span=(0, 4), match='x--x'>
3  x---x      <_sre.SRE_Match object; span=(0, 5), match='x---x'>
4  x----x     <_sre.SRE_Match object; span=(0, 6), match='x----x'>
5  x-----x    None
正規表示式匹配說明相同語法
< regex > {,n}任何小於或等於的重複次數n< regex > {0,n}
< regex > {m,}任何大於或等於的重複次數m----
< regex > {,}任意次數的重複< regex > {0,} , < regex > *
>>> re.search('x{}y', 'x{}y')
<_sre.SRE_Match object; span=(0, 4), match='x{}y'>
>>> re.search('x{foo}y', 'x{foo}y')
<_sre.SRE_Match object; span=(0, 7), match='x{foo}y'>
>>> re.search('x{a:b}y', 'x{a:b}y')
<_sre.SRE_Match object; span=(0, 7), match='x{a:b}y'>
>>> re.search('x{1,3,5}y', 'x{1,3,5}y')
<_sre.SRE_Match object; span=(0, 9), match='x{1,3,5}y'>
>>> re.search('x{foo,bar}y', 'x{foo,bar}y')
<_sre.SRE_Match object; span=(0, 11), match='x{foo,bar}y'>

{m,n}? 只匹配一次

非貪婪(懶惰)版本 {m,n}。

>>> re.search('a{3,5}', 'aaaaaaaa')
<_sre.SRE_Match object; span=(0, 5), match='aaaaa'>
>>> re.search('a{3,5}?', 'aaaaaaaa')
<_sre.SRE_Match object; span=(0, 3), match='aaa'>

類別5:分組構造和反向參照

分組構造將 Python 中的正規表示式分解為子表示式或組。

  • 分組:一個組代表一個單一的句法實體。附加元字元作為一個單元應用於整個組。
  • 捕獲:一些分組結構還捕獲與組中的子表示式匹配的搜尋字串部分。可以通過幾種不同的機制檢索捕獲的匹配項。

(<regex>),定義子表示式或組。

# 括號中的正規表示式僅匹配括號的內容
>>> re.search('(bar)', 'foo bar baz')
<_sre.SRE_Match object; span=(4, 7), match='bar'>
>>> re.search('bar', 'foo bar baz')
<_sre.SRE_Match object; span=(4, 7), match='bar'>

將組視為一個單元

組後面的量詞元字元對組中指定的整個子表示式作為一個單元進行操作。

# 元字元+僅適用於字元'r','ba'隨後出現一次或多次'r'。
>>> re.search('bar+', 'foo bar baz')
<_sre.SRE_Match object; span=(4, 7), match='bar'>
>>> re.search('(bar)+', 'foo bar baz')
<_sre.SRE_Match object; span=(4, 7), match='bar'>
>>> re.search('(bar)+', 'foo barbar baz')
<_sre.SRE_Match object; span=(4, 10), match='barbar'>
>>> re.search('(bar)+', 'foo barbarbarbar baz')
<_sre.SRE_Match object; span=(4, 16), match='barbarbarbar'>
正規表示式解釋匹配說明例子
bar+元字元+僅適用於字元’r’。‘ba’隨後出現一次或多次’r’bar、barr、barrr等
(bar)+元字元+適用於整個字串’bar’。出現一次或多次’bar’bar、barbar、barbarbar

捕獲組,m.groups()

返回一個元組,其中包含從正規表示式匹配中捕獲的所有組。

>>> m = re.search('(w+),(w+),(w+)', 'foo,quux,baz')
>>> m
<_sre.SRE_Match object; span=(0, 12), match='foo:quux:baz'>
>>> m.groups()
('foo', 'quux', 'baz')

捕獲組,m.group(<n>)

返回包含<n>捕獲的匹配項的字串。

>>> m = re.search('(w+),(w+),(w+)', 'foo,quux,baz')
>>> m.groups()
('foo', 'quux', 'baz')
>>> m.group(0)
('foo', 'quux', 'baz')
>>> m.group(1)
'foo'
>>> m.group(2)
'quux'
>>> m.group(3)
'baz'

捕獲組,m.group(<n1>, <n2>, …)

返回一個包含指定捕獲匹配序號的元組。

>>> m = re.search('(w+),(w+),(w+)', 'foo,quux,baz')
>>> m.groups()
('foo', 'quux', 'baz')
>>> m.group(2, 3)
('quux', 'baz')
>>> m.group(3, 2, 1)
('baz', 'quux', 'foo')

類別6:反向參照

<num> 匹配連續相同字元

>>> regex = r'(w+),1'

>>> m = re.search(regex, 'foo,foo')
>>> m
<_sre.SRE_Match object; span=(0, 7), match='foo,foo'>
>>> m.group(1)
'foo'

>>> m = re.search(regex, 'qux,qux')
>>> m
<_sre.SRE_Match object; span=(0, 7), match='qux,qux'>
>>> m.group(1)
'qux'

>>> m = re.search(regex, 'foo,qux')
>>> print(m)
None

類別7:其他分組結構

(?P<name><regex>) 建立捕獲組並命名

>>> m = re.search('(?P<w1>w+),(?P<w2>w+),(?P<w3>w+)', 'foo,quux,baz')
>>> m.groups()
('foo', 'quux', 'baz')

>>> m.group('w1')
'foo'
>>> m.group('w3')
'baz'
>>> m.group('w1', 'w2', 'w3')
('foo', 'quux', 'baz')
>>> m.group(1, 2, 3)
('foo', 'quux', 'baz')

(?P=<name>) 匹配先前捕獲名的內容

>>> m = re.search(r'(w+),1', 'foo,foo')
>>> m
<_sre.SRE_Match object; span=(0, 7), match='foo,foo'>
>>> m.group(1)
'foo'
>>> m = re.search(r'(?P<word>w+),(?P=word)', 'foo,foo')
>>> m
<_sre.SRE_Match object; span=(0, 7), match='foo,foo'>
>>> m.group('word')
'foo'

(?:<regex>) 建立一個非捕獲組

>>> m = re.search('(w+),(?:w+),(w+)', 'foo,quux,baz')
>>> m.groups()
('foo', 'baz')

>>> m.group(1)
'foo'
>>> m.group(2)
'baz'

指定條件匹配

(?(<n>)<yes-regex>|<no-regex>)

(?(<name>)<yes-regex>|<no-regex>)

# ^(###)?表示搜尋字串可選地以 . 開頭'###'。如果是這樣,那麼周圍的分組括號###將建立一個編號為的組1。否則,不會存在這樣的組
# foo字面上匹配字串'foo'
# (?(1)bar|baz)匹配'bar'組是否1存在和'baz'不存在
regex = r'^(###)?foo(?(1)bar|baz)'


# 搜尋字串'###foobar'確實以 開頭'###',因此解析器建立了一個編號為 的組1。然後條件匹配是針對'bar'匹配的
>>> re.search(regex, '###foobar')
<_sre.SRE_Match object; span=(0, 9), match='###foobar'>

# 搜尋字串'###foobaz'確實以 開頭'###',因此解析器建立了一個編號為 的組1。然後條件匹配是反對'bar',不匹配。
>>> print(re.search(regex, '###foobaz'))
None

# 搜尋字串'foobar'不以 開頭'###',因此沒有編號為 的組1。然後條件匹配是反對'baz',不匹配。
>>> print(re.search(regex, 'foobar'))
None

# 搜尋字串'foobaz'不以 開頭'###',因此沒有編號為 的組1。然後條件匹配是針對'baz'匹配的。
>>> re.search(regex, 'foobaz')
<_sre.SRE_Match object; span=(0, 6), match='foobaz'>

類別8:Lookahead 和 Lookbehind 斷言

根據解析器在搜尋字串中當前位置的後面(左側)或前面(右側)來確定 Python 中正規表示式匹配的成功或失敗。(?=<lookahead_regex>) 積極前瞻斷言

(?=<lookahead_regex>) 積極前瞻斷言

# 斷言正規表示式解析器當前位置之後的內容必須匹配
# 前瞻斷言(?=[a-z])指定後面的'foo'必須是小寫字母字元。
>>> re.search('foo(?=[a-z])', 'foobar')
<_sre.SRE_Match object; span=(0, 3), match='foo'>
# 前瞻失敗的例子,foo的下一個字元是'1'
>>> print(re.search('foo(?=[a-z])', 'foo123'))
None

# 前瞻的獨特之處<lookahead_regex>在於不消耗搜尋字串中匹配的部分,並且它不是返回的匹配物件的一部分。
>>> re.search('foo(?=[a-z])', 'foobar')
<_sre.SRE_Match object; span=(0, 3), match='foo'>

# 舉例對比觀察,?=斷言的區別
>>> m = re.search('foo(?=[a-z])(?P<ch>.)', 'foobar')
>>> m.group('ch')
'b'
>>> m = re.search('foo([a-z])(?P<ch>.)', 'foobar')
>>> m.group('ch')
'a'

(?!<lookahead_regex>) 否定的前瞻斷言

# 例子和之前的前瞻積極斷言相反
>>> re.search('foo(?=[a-z])', 'foobar')
<_sre.SRE_Match object; span=(0, 3), match='foo'>
>>> print(re.search('foo(?![a-z])', 'foobar'))
None

>>> print(re.search('foo(?=[a-z])', 'foo123'))
None
>>> re.search('foo(?![a-z])', 'foo123')
<_sre.SRE_Match object; span=(0, 3), match='foo'>

(?<=<lookbehind_regex>) 積極的後向斷言

# 斷言正規表示式解析器當前位置之前的內容匹配
# 斷言指定'foo'必須先於'bar'
>>> re.search('(?<=foo)bar', 'foobar')
<_sre.SRE_Match object; span=(3, 6), match='bar'>
>>> print(re.search('(?<=qux)bar', 'foobar'))
None

(?<!–<lookbehind_regex–>) 否定的向後斷言

# 例子和之前的向後積極斷言相反
>>> print(re.search('(?<!foo)bar', 'foobar'))
None
>>> re.search('(?<!qux)bar', 'foobar')
<_sre.SRE_Match object; span=(3, 6), match='bar'>

類別9:雜項元字元

(?#…) 指定註釋

# 正規表示式解析器忽略(?#...)序列中包含的任何內容
>>> re.search('bar(?#This is a comment) *baz', 'foo bar baz qux')
<_sre.SRE_Match object; span=(4, 11), match='bar baz'>

豎條或管道 ( | ) 指定要匹配的一組備選方案

# 形式的表示式最多匹配一個指定的表示式:<regex1>|<regex2>|...|<regexn><regexi>
>>> re.search('foo|bar|baz', 'bar')
<_sre.SRE_Match object; span=(0, 3), match='bar'>
>>> re.search('foo|bar|baz', 'baz')
<_sre.SRE_Match object; span=(0, 3), match='baz'>
>>> print(re.search('foo|bar|baz', 'quux'))
None

# 結合交替、分組和任何其他元字元來實現您需要的任何複雜程度。
# (foo|bar|baz)+表示一個或多個字串
>>> re.search('(foo|bar|baz)+', 'foofoofoo')
<_sre.SRE_Match object; span=(0, 9), match='foofoofoo'>
>>> re.search('(foo|bar|baz)+', 'bazbazbazbaz')
<_sre.SRE_Match object; span=(0, 12), match='bazbazbazbaz'>
>>> re.search('(foo|bar|baz)+', 'barbazfoo')
<_sre.SRE_Match object; span=(0, 9), match='barbazfoo'>

# ([0-9]+|[a-f]+)表示一個或多個十進位制數位字元的序列或一個或多個'a-f'字元的序列
>>> re.search('([0-9]+|[a-f]+)', '456')
<_sre.SRE_Match object; span=(0, 3), match='456'>
>>> re.search('([0-9]+|[a-f]+)', 'ffda')
<_sre.SRE_Match object; span=(0, 4), match='ffda'>

到此這篇關於Python中re模組的元字元使用小結的文章就介紹到這了,更多相關Python中re模組的元字元內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com