Python中re模塊的元字符使用小結
元字符(Meta Characters)是正則表達式中具有特殊意義的專用字符,在Python中也不例外,是用來指明前導字符(位于元字符前的字符)在目標對象中的出現(xiàn)模式。
在正則表達式中,方括號 ( [] ) 中指定的一組字符組成一個字符類。
# 元字符序列匹配類中的任何單個字符 >>> s = 'foo123bar' # 3個任意連續(xù)字符匹配 >>> 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模塊支持的元字符
下面列表都是元字符的描述,對元字符進行分類描述方便記憶。 這個要是看不懂直接看跳過看下面的例子。
字符 | 描述 |
---|---|
\ | 將下一個字符標記為一個特殊字符、或一個原義字符、或一個 向后引用、或一個八進制轉(zhuǎn)義符。例如,‘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 是一個非負整數(shù)。匹配確定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的兩個 o。 |
{n,} | n 是一個非負整數(shù)。至少匹配n 次。例如,‘o{2,}’ 不能匹配 “Bob” 中的 ‘o’,但能匹配 “foooood” 中的所有 o。‘o{1,}’ 等價于 ‘o+’。‘o{0,}’ 則等價于 ‘o*’。 |
{n,m} | m 和 n 均為非負整數(shù),其中n <= m。最少匹配 n 次且最多匹配 m 次。例如,“o{1,3}” 將匹配 “fooooood” 中的前三個 o。‘o{0,1}’ 等價于 ‘o?’。請注意在逗號和兩個數(shù)之間不能有空格。 |
? | 當該字符緊跟在任何一個其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面時,匹配模式是非貪婪的。非貪婪模式盡可能少的匹配所搜索的字符串,而默認的貪婪模式則盡可能多的匹配所搜索的字符串。例如,對于字符串 “oooo”,‘o+?’ 將匹配單個 “o”,而 ‘o+’ 將匹配所有 ‘o’。 |
. | 匹配除換行符(\n、\r)之外的任何單個字符。要匹配包括 ‘\n’ 在內(nèi)的任何字符,請使用像"(. |
x|y | 匹配 x 或 y。例如,'z |
[xyz] | 字符集合。匹配所包含的任意一個字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。 |
[^xyz] | 負值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p’、‘l’、‘i’、‘n’。 |
[a-z] | 字符范圍。匹配指定范圍內(nèi)的任意字符。例如,‘[a-z]’ 可以匹配 ‘a’ 到 ‘z’ 范圍內(nèi)的任意小寫字母字符。 |
[^a-z] | 負值字符范圍。匹配任何不在指定范圍內(nèi)的任意字符。例如,‘[^a-z]’ 可以匹配任何不在 ‘a’ 到 ‘z’ 范圍內(nèi)的任意字符。 |
\b | 匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, ‘er\b’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’。 |
\B | 匹配非單詞邊界。‘er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’。 |
\cx | 匹配由 x 指明的控制字符。例如, \cM 匹配一個 Control-M 或回車符。x 的值必須為 A-Z 或 a-z 之一。否則,將 c 視為一個原義的 ‘c’ 字符。 |
\d | 匹配一個數(shù)字字符。等價于 [0-9]。 |
\D | 匹配一個非數(shù)字字符。等價于 [^0-9]。 |
\f | 匹配一個換頁符。等價于 \x0c 和 \cL。 |
\n | 匹配一個換行符。等價于 \x0a 和 \cJ。 |
\r | 匹配一個回車符。等價于 \x0d 和 \cM。 |
\s | 匹配任何空白字符,包括空格、制表符、換頁符等等。等價于 [ \f\n\r\t\v]。 |
\S | 匹配任何非空白字符。等價于 [^ \f\n\r\t\v]。 |
\t | 匹配一個制表符。等價于 \x09 和 \cI。 |
\v | 匹配一個垂直制表符。等價于 \x0b 和 \cK。 |
\w | 匹配字母、數(shù)字、下劃線。等價于’[A-Za-z0-9_]'。 |
\W | 匹配非字母、數(shù)字、下劃線。等價于 ‘[^A-Za-z0-9_]’。 |
\xn | 匹配 n,其中 n 為十六進制轉(zhuǎn)義值。十六進制轉(zhuǎn)義值必須為確定的兩個數(shù)字長。例如,‘\x41’ 匹配 “A”。‘\x041’ 則等價于 ‘\x04’ & “1”。正則表達式中可以使用 ASCII 編碼。 |
\num | 匹配 num,其中 num 是一個正整數(shù)。對所獲取的匹配的引用。例如,‘(.)\1’ 匹配兩個連續(xù)的相同字符。 |
\n | 標識一個八進制轉(zhuǎn)義值或一個向后引用。如果 \n 之前至少 n 個獲取的子表達式,則 n 為向后引用。否則,如果 n 為八進制數(shù)字 (0-7),則 n 為一個八進制轉(zhuǎn)義值。 |
\nm | 標識一個八進制轉(zhuǎn)義值或一個向后引用。如果 \nm 之前至少有 nm 個獲得子表達式,則 nm 為向后引用。如果 \nm 之前至少有 n 個獲取,則 n 為一個后跟文字 m 的向后引用。如果前面的條件都不滿足,若 n 和 m 均為八進制數(shù)字 (0-7),則 \nm 將匹配八進制轉(zhuǎn)義值 nm。 |
\nml | 如果 n 為八進制數(shù)字 (0-3),且 m 和 l 均為八進制數(shù)字 (0-7),則匹配八進制轉(zhuǎn)義值 nml。 |
\un | 匹配 n,其中 n 是一個用四個十六進制數(shù)字表示的 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]之間任何數(shù)字字符。
>>> re.search('[0-9][0-9]', 'foo123bar') <_sre.SRE_Match object; span=(3, 5), match='12'>
[0-9a-fA-F]匹配任何十六進制數(shù)字字符。
>>> re.search('[0-9a-fA-f]', '--- a0 ---') <_sre.SRE_Match object; span=(4, 5), match='a'>
[^0-9]匹配任何不是數(shù)字的字符開頭的字符。
>>> re.search('[^0-9]', '12345foo') <_sre.SRE_Match object; span=(5, 6), match='f'>
如果一個^字符出現(xiàn)在字符類中但不是第一個字符則無結果。
>>> re.search('[#:^]', 'foo^bar:baz#qux') <_sre.SRE_Match object; span=(3, 4), match='^'>
可以通過用連字符分隔字符來指定字符類中的字符范圍,可以將其作為第一個或最后一個字符放置,或者使用反斜杠 ( \ ) 對其進行轉(zhuǎn)義。
# 直接查找符號 >>> 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='-'> # 查找轉(zhuǎn)義符號 >>> 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=']'> # [ ] 內(nèi)的元字符失去意義轉(zhuǎn)義成字符處理 >>> 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', 'foo\nbar')) None >>> print(re.search('foo.bar', 'foosbar')) <_sre.SRE_Match object; span=(0, 7), match='foosbar'>
\w 和 \W 單詞字符匹配
\w匹配任何字母數(shù)字字符,單詞字符是大寫和小寫字母、數(shù)字和下劃線 ( _) 字符。
\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 字符十進制數(shù)字匹配
\d匹配任何十進制數(shù)字字符,等價于[0-9]。
>>> re.search('\d', 'abc4def') <_sre.SRE_Match object; span=(3, 4), match='4'>
\D匹配任何不是十進制數(shù)字的字符,等價于[^0-9]。
>>> re.search('\D', '234Q678') <_sre.SRE_Match object; span=(3, 4), match='Q'>
\s 和 \S 字符空格匹配
\s匹配任何空白字符,同時也匹配換行符。
>>> re.search('\s', 'foo\nbar 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
字符類序列\(zhòng)w, \W, \d, \D, \s, 和\S也可以出現(xiàn)在方括號字符類中。
# [\d\w\s]匹配任何數(shù)字、單詞或空白字符 >>> re.search('[\d\w\s]', '---3---') <_sre.SRE_Match object; span=(3, 4), match='3'> >>> re.search('[\d\w\s]', '---a---') <_sre.SRE_Match object; span=(3, 4), match='a'> >>> re.search('[\d\w\s]', '--- ---') <_sre.SRE_Match object; span=(3, 4), match=' '> # 由于\w包含\d,相同的字符類也可以表示為略短[\w\s] >>> re.search('[\w\s]', '---a---') <_sre.SRE_Match object; span=(3, 4), match='a'> >>> re.search('[\w\s]', '---a---') <_sre.SRE_Match object; span=(3, 4), match='a'> >>> re.search('[\w\s]', '--- ---') <_sre.SRE_Match object; span=(3, 4), match=' '>
類別2:轉(zhuǎn)義元字符
反斜杠 ( \ ) 轉(zhuǎn)義元字符
反斜杠會刪除元字符的特殊含義。
>>> 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'\\', 'foo\bar') <_sre.SRE_Match object; span=(3, 4), match='\\'>
類別3:錨點
不匹配搜索字符串中的任何實際字符,并且在解析期間它們不使用任何搜索字符串。指示搜索字符串中必須發(fā)生匹配的特定位置。
^ 和 \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('bar\Z', 'foobar') <_sre.SRE_Match object; span=(3, 6), match='bar'> >>> print(re.search('bar\Z', 'barfoo')) None # 特殊$也在搜索字符串末尾的單個換行符之前匹配 >>> re.search('bar$', 'foobar\n') <_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'foo\b', 'foo bar') <_sre.SRE_Match object; span=(0, 3), match='foo'> >>> re.search(r'foo\b', 'foo.bar') <_sre.SRE_Match object; span=(0, 3), match='foo'> >>> print(re.search(r'foo\b', 'foobar')) None # 單詞居中 >>> re.search(r'\bbar\b', 'foo bar baz') <_sre.SRE_Match object; span=(4, 7), match='bar'> >>> re.search(r'\bbar\b', 'foo(bar)baz') <_sre.SRE_Match object; span=(4, 7), match='bar'> >>> print(re.search(r'\bbar\b', 'foobarbaz')) None
\B 不能在單詞的開頭或結尾。
>>> print(re.search(r'\Bfoo\B', 'foo')) None >>> print(re.search(r'\Bfoo\B', '.foo.')) None >>> re.search(r'\Bfoo\B', 'barfoobaz') <_sre.SRE_Match object; span=(3, 6), match='foo'>
類別4:量詞
該部分必須出現(xiàn)多少次才能使匹配成功。
* 匹配前面的子表達式零次或多次
>>> 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個字符中全部的內(nèi)容。
>>> 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} 匹配前面正則表達式的任意數(shù)量的重復從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} | 任何小于或等于的重復次數(shù)n | < regex > {0,n} |
< regex > {m,} | 任何大于或等于的重復次數(shù)m | ---- |
< regex > {,} | 任意次數(shù)的重復 | < 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>),定義子表達式或組。
# 括號中的正則表達式僅匹配括號的內(nèi)容 >>> 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'隨后出現(xiàn)一次或多次'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’隨后出現(xiàn)一次或多次’r’ | bar、barr、barrr等 |
(bar)+ | 元字符+適用于整個字符串’bar’。 | 出現(xiàn)一次或多次’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> 匹配連續(xù)相同字符
>>> 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>) 創(chuàng)建捕獲組并命名
>>> 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>) 匹配先前捕獲名的內(nèi)容
>>> 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>) 創(chuàng)建一個非捕獲組
>>> 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>)
# ^(###)?表示搜索字符串可選地以 . 開頭'###'。如果是這樣,那么周圍的分組括號###將創(chuàng)建一個編號為的組1。否則,不會存在這樣的組 # foo字面上匹配字符串'foo' # (?(1)bar|baz)匹配'bar'組是否1存在和'baz'不存在 regex = r'^(###)?foo(?(1)bar|baz)' # 搜索字符串'###foobar'確實以 開頭'###',因此解析器創(chuàng)建了一個編號為 的組1。然后條件匹配是針對'bar'匹配的 >>> re.search(regex, '###foobar') <_sre.SRE_Match object; span=(0, 9), match='###foobar'> # 搜索字符串'###foobaz'確實以 開頭'###',因此解析器創(chuàng)建了一個編號為 的組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 斷言
根據(jù)解析器在搜索字符串中當前位置的后面(左側(cè))或前面(右側(cè))來確定 Python 中正則表達式匹配的成功或失敗。(?=<lookahead_regex>) 積極前瞻斷言
(?=<lookahead_regex>) 積極前瞻斷言
# 斷言正則表達式解析器當前位置之后的內(nèi)容必須匹配 # 前瞻斷言(?=[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'> # 舉例對比觀察,?=斷言的區(qū)別 >>> 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>) 積極的后向斷言
# 斷言正則表達式解析器當前位置之前的內(nèi)容匹配 # 斷言指定'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:雜項元字符
(?#…) 指定注釋
# 正則表達式解析器忽略(?#...)序列中包含的任何內(nèi)容 >>> 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 # 結合交替、分組和任何其他元字符來實現(xiàn)您需要的任何復雜程度。 # (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]+)表示一個或多個十進制數(shù)字字符的序列或一個或多個'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模塊的元字符內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
基于Python+Pygame實現(xiàn)經(jīng)典賽車游戲
這篇文章主要為大家分享了一個基于Python和Pygame實現(xiàn)的賽車小游戲,文中的示例代碼講解詳細,對我們學習Python有一定幫助,需要的可以參考一下2022-04-04django數(shù)據(jù)模型(Model)的字段類型解析
這篇文章主要介紹了django數(shù)據(jù)模型(Model)的字段類型,文中給大家提到了django數(shù)據(jù)模型on_delete, db_constraint的使用,需要的朋友可以參考下2019-12-12python通過apply使用元祖和列表調(diào)用函數(shù)實例
這篇文章主要介紹了python通過apply使用元祖和列表調(diào)用函數(shù),實例分析了python中apply方法的使用技巧,需要的朋友可以參考下2015-05-05