Python中re模块的元字符使用小结

目录
  • 类别1:匹配单个字符的元字符
    • 方括号( [] ) 字符集
    • 点 ( . ) 通配符
    • \w 和 \W 单词字符匹配
    • \d 和 \D 字符十进制数字匹配
    • \s 和 \S 字符空格匹配
    • 混合使用 \w, \W, \d, \D, \s, 和\S
  • 类别2:转义元字符
    • 反斜杠 ( \ ) 转义元字符
  • 类别3:锚点
    • $ 和\Z 字符串的结尾匹配项
    • \b 和 \B 单词匹配
  • 类别4:量词
    • * 匹配前面的子表达式零次或多次
    • + 匹配前面的子表达式一次或多次
    • ? 匹配前面的子表达式零次或一次
    • .*?、+?、?? 最小长度匹配
    • {m} 完全匹配m次前面元字符的正则表达式。
    • {m,n} 匹配前面正则表达式的任意数量的重复从m到n次
    • {m,n}? 只匹配一次
  • 类别5:分组构造和反向引用
    • 将组视为一个单元
    • 捕获组,m.groups()
    • 捕获组,m.group(<n>)
    • 捕获组,m.group(<n1>, <n2>, …)
  • 类别6:反向引用
    • \<num> 匹配连续相同字符
  • 类别7:其他分组结构
    • (?P<name><regex>) 创建捕获组并命名
    • (?P=<name>) 匹配先前捕获名的内容
    • (?:<regex>) 创建一个非捕获组
    • 指定条件匹配
  • 类别8:Lookahead 和 Lookbehind 断言
    • (?=<lookahead_regex>) 积极前瞻断言
    • (?!<lookahead_regex>) 否定的前瞻断言
    • (?<=<lookbehind_regex>) 积极的后向断言
    • (?<!–<lookbehind_regex–>) 否定的向后断言
  • 类别9:杂项元字符
    • (?#…) 指定注释
    • 竖条或管道 ( | ) 指定要匹配的一组备选方案

元字符(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 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘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 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个非数字字符。等价于 [^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 匹配字母、数字、下划线。等价于’[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', 'foo\nbar'))
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', '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

字符类序列\w, \W, \d, \D, \s, 和\S也可以出现在方括号字符类中。

# [\d\w\s]匹配任何数字、单词或空白字符

>>> 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:转义元字符

反斜杠 ( \ ) 转义元字符

反斜杠会删除元字符的特殊含义。

>>> 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:锚点

不匹配搜索字符串中的任何实际字符,并且在解析期间它们不使用任何搜索字符串。指示搜索字符串中必须发生匹配的特定位置。

^ 和 \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:量词

该部分必须出现多少次才能使匹配成功。

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

>>> 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模块的元字符内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Python正则表达式和元字符详解

    正则表达式 正则表达式是一种强大的字符串操作工具.它是一种领域特定语言 (DSL),不管是 Python 还是在大多数现代编程语言中都是作为库存在. 它们主要面向两种任务: - 验证字符串是否与模式匹配 (例如,字符串具有电子邮件地址的格式). - 在字符串中执行替换(例如将所有大写字母改成小写字母). 特定于领域的语言是高度专业化的迷你编程语言. 正则表达式是一个例子,SQL(用于数据库操作)是另一个例子. 私有领域特定语言通常用于特定的工业目的. Python 的正则表达式可以使用 re 模

  • Python元字符的用法实例解析

    反斜杠的作用: 要想将一个元字符^当一个普通字符处理,加反斜杠 例如: >>>import re >>>r=r'\^abc' >>>re.findall(r,'^abc ^abc ^abc') ['^abc','^abc','^abc'] \d匹配任何十进制数,它相当于类[0-9]. \D匹配任何非数字字符,它相当于类[^0-9] \s匹配任何空白字符,他相当于类[\t\n\r\f\v] \S匹配任何非空白字符,它相当于类[^\t\n\r\f\v] \

  • Python re正则表达式元字符分组()用法分享

    分组小括号() 有直接分组和命名分组 直接分组: ()分组只显示小括号括起来的内容 re.findall(r"(name)+","namename") 这里匹配到了namename 但是值显示括号中的name 直接分组实例 re.search()方法: 搜索结果返回对象,可以用ret.group()方法打印结果 它跟findall不同在于找到一个结果就不再往下找了 re.match()方法: 只匹配字符串开始的位置 有名分组: 给分组取名?P<name>

  • Python中re模块的元字符使用小结

    目录 类别1:匹配单个字符的元字符 方括号( [] ) 字符集 点 ( . ) 通配符 \w 和 \W 单词字符匹配 \d 和 \D 字符十进制数字匹配 \s 和 \S 字符空格匹配 混合使用 \w, \W, \d, \D, \s, 和\S 类别2:转义元字符 反斜杠 ( \ ) 转义元字符 类别3:锚点 $ 和\Z 字符串的结尾匹配项 \b 和 \B 单词匹配 类别4:量词 * 匹配前面的子表达式零次或多次 + 匹配前面的子表达式一次或多次 ? 匹配前面的子表达式零次或一次 .*?.+?.??

  • Python中numpy模块常见用法demo实例小结

    本文实例总结了Python中numpy模块常见用法.分享给大家供大家参考,具体如下: import numpy as np arr = np.array([[1,2,3], [2,3,4]]) print(arr) print(type(arr)) print('number of dim:', arr.ndim) print('shape:', arr.shape) print('size:', arr.size) [[1 2 3]  [2 3 4]] number of dim: 2 sha

  • Python中asyncio模块的深入讲解

    1. 概述 Python中 asyncio 模块内置了对异步IO的支持,用于处理异步IO:是Python 3.4版本引入的标准库. asyncio 的编程模型就是一个消息循环.我们从 asyncio 块中直接获取一个 EventLoop 的引用,然后把需要执行的协程扔到 EventLoop 中执行,就实现了异步IO. 2. 用asyncio实现Hello world #!/usr/bin/env python3 # -*- coding: utf-8 -*- # @Time : 2019/1/9

  • python中pdb模块实例用法

    大家可能都不大熟悉关于pdb这个模块,实际上就是python中的内置模块,主要作用于命令行调试代码,下面我们将通过是哪个小结给大家详细介绍下使用该内容的方式,首先是简单介绍,然后为大家呈现实例,最后就是总结啦,小伙伴是不是相当期待呢,那就板正做好,一起来详细了解下吧~ 简单介绍: 添加断点-代码后添加一行 pdb.set_trace() 命令行添加断点 b line_number 常见命令: 进入命令行Debug模式,python -m pdb xxx.py h:(help)帮助 w:(wher

  • python中pygame模块用法实例

    本文实例讲述了python中pygame模块用法,分享给大家供大家参考.具体方法如下: import pygame, sys from pygame.locals import * #set up pygame pygame.init() windowSurface = pygame.display.set_mode((500, 400), 0, 32) pygame.display.set_caption("hello, world") BLACK = (0, 0, 0) WHITE

  • python中string模块各属性以及函数的用法介绍

    任何语言都离不开字符,那就会涉及对字符的操作,尤其是脚本语言更是频繁,不管是生产环境还是面试考验都要面对字符串的操作. python的字符串操作通过2部分的方法函数基本上就可以解决所有的字符串操作需求: • python的字符串属性函数 • python的string模块 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 1.字符串属性函数  系统版本:CentOS release 6.2 (Final)2.6.32-220.

  • Python中itertools模块用法详解

    本文实例讲述了Python中itertools模块用法,分享给大家供大家参考.具体分析如下: 一般来说,itertools模块包含创建有效迭代器的函数,可以用各种方式对数据进行循环操作,此模块中的所有函数返回的迭代器都可以与for循环语句以及其他包含迭代器(如生成器和生成器表达式)的函数联合使用. chain(iter1, iter2, ..., iterN): 给出一组迭代器(iter1, iter2, ..., iterN),此函数创建一个新迭代器来将所有的迭代器链接起来,返回的迭代器从it

  • Python中optionParser模块的使用方法实例教程

    本文以实例形式较为详尽的讲述了Python中optionParser模块的使用方法,对于深入学习Python有很好的借鉴价值.分享给大家供大家参考之用.具体分析如下: 一般来说,Python中有两个内建的模块用于处理命令行参数: 一个是 getopt,<Deep in python>一书中也有提到,只能简单处理 命令行参数: 另一个是 optparse,它功能强大,而且易于使用,可以方便地生成标准的.符合Unix/Posix 规范的命令行说明. 示例如下: from optparse impo

  • python中urllib模块用法实例详解

    本文实例讲述了python中urllib模块用法.分享给大家供大家参考.具体分析如下: 一.问题: 近期公司项目的需求是根据客户提供的api,我们定时去获取数据, 之前的方案是用php收集任务存入到redis队列,然后在linux下做一个常驻进程跑某一个php文件, 该php文件就一个无限循环,判断redis队列,有就执行,没有就break. 二.解决方法: 最近刚好学了一下python, python的urllib模块或许比php的curl更快,而且简单. 贴一下代码 复制代码 代码如下: #

  • python中hashlib模块用法示例

    我们以前介绍过一篇Python加密的文章:Python 加密的实例详解.今天我们看看python中hashlib模块用法示例,具体如下. hashlib hashlib主要提供字符加密功能,将md5和sha模块整合到了一起,支持md5,sha1, sha224, sha256, sha384, sha512等算法 具体应用 #!/usr/bin/env python # -*- coding: UTF-8 -*- #pyversion:python3.5 #owner:fuzj import h

随机推荐