首页  >  文章  >  后端开发  >  Python中re模块的元字符怎么使用

Python中re模块的元字符怎么使用

WBOY
WBOY转载
2023-06-02 20:19:351590浏览

元字符(Meta Characters)是正则表达式中具有特殊意义的专用字符,在Python中也不例外,是用来指明前导字符(位于元字符前的字符)在目标对象中的出现模式。

在正则表达式中,方括号 ( [] ) 中指定的一组字符组成一个字符类。

# 元字符序列匹配类中的任何单个字符
>>> s = 'foo123bar'

# 3个任意连续字符匹配
>>> re.search('[0-9][0-9][0-9]', s)
<_sre.SRE_Match object; span=(3, 6), match=&#39;123&#39;>

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

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

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

# 匹配不上的情况
>>> print(re.search(&#39;[0-9][0-9][0-9]&#39;, &#39;12foo34&#39;))
None

通配符点 ( . ) 元字符匹配除换行符以外的任何字符。

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

>>> s = &#39;foo13bar&#39;
>>> print(re.search(&#39;1.3&#39;, s))
None

re模块支持的元字符

Python中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 c243cc1d462eb95d1cb80c0f4637aa8a {,n} 任何小于或等于的重复次数n 2386d67d7a94bbcacc6d6e11cdb07010 {0,n}
2386d67d7a94bbcacc6d6e11cdb07010 {m,} 任何大于或等于的重复次数m ----
2386d67d7a94bbcacc6d6e11cdb07010 {,} 任意次数的重复 2386d67d7a94bbcacc6d6e11cdb07010 {0,} , 2386d67d7a94bbcacc6d6e11cdb07010 *
>>> re.search(&#39;x{}y&#39;, &#39;x{}y&#39;)
<_sre.SRE_Match object; span=(0, 4), match=&#39;x{}y&#39;>
>>> re.search(&#39;x{foo}y&#39;, &#39;x{foo}y&#39;)
<_sre.SRE_Match object; span=(0, 7), match=&#39;x{foo}y&#39;>
>>> re.search(&#39;x{a:b}y&#39;, &#39;x{a:b}y&#39;)
<_sre.SRE_Match object; span=(0, 7), match=&#39;x{a:b}y&#39;>
>>> re.search(&#39;x{1,3,5}y&#39;, &#39;x{1,3,5}y&#39;)
<_sre.SRE_Match object; span=(0, 9), match=&#39;x{1,3,5}y&#39;>
>>> re.search(&#39;x{foo,bar}y&#39;, &#39;x{foo,bar}y&#39;)
<_sre.SRE_Match object; span=(0, 11), match=&#39;x{foo,bar}y&#39;>

{m,n}? 只匹配一次

非贪婪(懒惰)版本 {m,n}。

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

类别5:分组构造和反向引用

分组构造将 Python 中的正则表达式分解为子表达式或组。

  • 分组:一个组代表一个单一的句法实体。附加元字符作为一个单元应用于整个组。

  • 捕获:一些分组结构还捕获与组中的子表达式匹配的搜索字符串部分。可以通过几种不同的机制检索捕获的匹配项。

(8b2d503d09b38f6c300ed08e7e08a623),定义子表达式或组。

# 括号中的正则表达式仅匹配括号的内容
>>> re.search(&#39;(bar)&#39;, &#39;foo bar baz&#39;)
<_sre.SRE_Match object; span=(4, 7), match=&#39;bar&#39;>
>>> re.search(&#39;bar&#39;, &#39;foo bar baz&#39;)
<_sre.SRE_Match object; span=(4, 7), match=&#39;bar&#39;>

将组视为一个单元

组后面的量词元字符对组中指定的整个子表达式作为一个单元进行操作。

# 元字符+仅适用于字符&#39;r&#39;,&#39;ba&#39;随后出现一次或多次&#39;r&#39;。
>>> re.search(&#39;bar+&#39;, &#39;foo bar baz&#39;)
<_sre.SRE_Match object; span=(4, 7), match=&#39;bar&#39;>
>>> re.search(&#39;(bar)+&#39;, &#39;foo bar baz&#39;)
<_sre.SRE_Match object; span=(4, 7), match=&#39;bar&#39;>
>>> re.search(&#39;(bar)+&#39;, &#39;foo barbar baz&#39;)
<_sre.SRE_Match object; span=(4, 10), match=&#39;barbar&#39;>
>>> re.search(&#39;(bar)+&#39;, &#39;foo barbarbarbar baz&#39;)
<_sre.SRE_Match object; span=(4, 16), match=&#39;barbarbarbar&#39;>
正则表达式 解释 匹配说明 例子
bar+ 元字符+仅适用于字符’r’。 ‘ba’随后出现一次或多次’r’ bar、barr、barrr等
(bar)+ 元字符+适用于整个字符串’bar’。 出现一次或多次’bar’ bar、barbar、barbarbar

捕获组,m.groups()

返回一个元组,其中包含从正则表达式匹配中捕获的所有组。

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

捕获组,m.group(751fecf49c9d13ca89ee2cbb9b75d4f6)

返回包含751fecf49c9d13ca89ee2cbb9b75d4f6捕获的匹配项的字符串。

>>> m = re.search(&#39;(\w+),(\w+),(\w+)&#39;, &#39;foo,quux,baz&#39;)
>>> m.groups()
(&#39;foo&#39;, &#39;quux&#39;, &#39;baz&#39;)
>>> m.group(0)
(&#39;foo&#39;, &#39;quux&#39;, &#39;baz&#39;)
>>> m.group(1)
&#39;foo&#39;
>>> m.group(2)
&#39;quux&#39;
>>> m.group(3)
&#39;baz&#39;

捕获组,m.group(9bf5d5f78ce02c1cdb76211e9c3c0d58, 5b22540881a269e0dad53a835b4dc6c1, …)

返回一个包含指定捕获匹配序号的元组。

>>> m = re.search(&#39;(\w+),(\w+),(\w+)&#39;, &#39;foo,quux,baz&#39;)
>>> m.groups()
(&#39;foo&#39;, &#39;quux&#39;, &#39;baz&#39;)
>>> m.group(2, 3)
(&#39;quux&#39;, &#39;baz&#39;)
>>> m.group(3, 2, 1)
(&#39;baz&#39;, &#39;quux&#39;, &#39;foo&#39;)

类别6:反向引用

\d2c1e15f2758ae4ead444247148d09ea 匹配连续相同字符

>>> regex = r&#39;(\w+),\1&#39;

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

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

>>> m = re.search(regex, &#39;foo,qux&#39;)
>>> print(m)
None

类别7:其他分组结构

(?P8a11bc632ea32a57b3e3693c7987c4208b2d503d09b38f6c300ed08e7e08a623) 创建捕获组并命名

>>> m = re.search(&#39;(?P<w1>\w+),(?P<w2>\w+),(?P<w3>\w+)&#39;, &#39;foo,quux,baz&#39;)
>>> m.groups()
(&#39;foo&#39;, &#39;quux&#39;, &#39;baz&#39;)

>>> m.group(&#39;w1&#39;)
&#39;foo&#39;
>>> m.group(&#39;w3&#39;)
&#39;baz&#39;
>>> m.group(&#39;w1&#39;, &#39;w2&#39;, &#39;w3&#39;)
(&#39;foo&#39;, &#39;quux&#39;, &#39;baz&#39;)
>>> m.group(1, 2, 3)
(&#39;foo&#39;, &#39;quux&#39;, &#39;baz&#39;)

(?P=8a11bc632ea32a57b3e3693c7987c420) 匹配先前捕获名的内容

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

(?:8b2d503d09b38f6c300ed08e7e08a623) 创建一个非捕获组

>>> m = re.search(&#39;(\w+),(?:\w+),(\w+)&#39;, &#39;foo,quux,baz&#39;)
>>> m.groups()
(&#39;foo&#39;, &#39;baz&#39;)

>>> m.group(1)
&#39;foo&#39;
>>> m.group(2)
&#39;baz&#39;

指定条件匹配

(?(751fecf49c9d13ca89ee2cbb9b75d4f6)e54221ffa845a2e7ae172bd995c518ee|cd0ccdd55bc66eea39ca4fc3945e2e03)

(?(8a11bc632ea32a57b3e3693c7987c420)e54221ffa845a2e7ae172bd995c518ee|cd0ccdd55bc66eea39ca4fc3945e2e03)

# ^(###)?表示搜索字符串可选地以 . 开头&#39;###&#39;。如果是这样,那么周围的分组括号###将创建一个编号为的组1。否则,不会存在这样的组
# foo字面上匹配字符串&#39;foo&#39;
# (?(1)bar|baz)匹配&#39;bar&#39;组是否1存在和&#39;baz&#39;不存在
regex = r&#39;^(###)?foo(?(1)bar|baz)&#39;


# 搜索字符串&#39;###foobar&#39;确实以 开头&#39;###&#39;,因此解析器创建了一个编号为 的组1。然后条件匹配是针对&#39;bar&#39;匹配的
>>> re.search(regex, &#39;###foobar&#39;)
<_sre.SRE_Match object; span=(0, 9), match=&#39;###foobar&#39;>

# 搜索字符串&#39;###foobaz&#39;确实以 开头&#39;###&#39;,因此解析器创建了一个编号为 的组1。然后条件匹配是反对&#39;bar&#39;,不匹配。
>>> print(re.search(regex, &#39;###foobaz&#39;))
None

# 搜索字符串&#39;foobar&#39;不以 开头&#39;###&#39;,因此没有编号为 的组1。然后条件匹配是反对&#39;baz&#39;,不匹配。
>>> print(re.search(regex, &#39;foobar&#39;))
None

# 搜索字符串&#39;foobaz&#39;不以 开头&#39;###&#39;,因此没有编号为 的组1。然后条件匹配是针对&#39;baz&#39;匹配的。
>>> re.search(regex, &#39;foobaz&#39;)
<_sre.SRE_Match object; span=(0, 6), match=&#39;foobaz&#39;>

类别8:Lookahead 和 Lookbehind 断言

根据解析器在搜索字符串中当前位置的后面(左侧)或前面(右侧)来确定 Python 中正则表达式匹配的成功或失败。积极前瞻断言可表示为:(?=lookahead_regex)

(?=a4e759c7b3da8f3b62a0d6ba87847c9a) 积极前瞻断言

# 断言正则表达式解析器当前位置之后的内容必须匹配
# 前瞻断言(?=[a-z])指定后面的&#39;foo&#39;必须是小写字母字符。
>>> re.search(&#39;foo(?=[a-z])&#39;, &#39;foobar&#39;)
<_sre.SRE_Match object; span=(0, 3), match=&#39;foo&#39;>
# 前瞻失败的例子,foo的下一个字符是&#39;1&#39;
>>> print(re.search(&#39;foo(?=[a-z])&#39;, &#39;foo123&#39;))
None

# 前瞻的独特之处<lookahead_regex>在于不消耗搜索字符串中匹配的部分,并且它不是返回的匹配对象的一部分。
>>> re.search(&#39;foo(?=[a-z])&#39;, &#39;foobar&#39;)
<_sre.SRE_Match object; span=(0, 3), match=&#39;foo&#39;>

# 举例对比观察,?=断言的区别
>>> m = re.search(&#39;foo(?=[a-z])(?P<ch>.)&#39;, &#39;foobar&#39;)
>>> m.group(&#39;ch&#39;)
&#39;b&#39;
>>> m = re.search(&#39;foo([a-z])(?P<ch>.)&#39;, &#39;foobar&#39;)
>>> m.group(&#39;ch&#39;)
&#39;a&#39;

(?!a4e759c7b3da8f3b62a0d6ba87847c9a) 否定的前瞻断言

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

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

(?74d0e88e682609072be49135468409a3) 积极的后向断言

# 断言正则表达式解析器当前位置之前的内容匹配
# 断言指定&#39;foo&#39;必须先于&#39;bar&#39;
>>> re.search(&#39;(?<=foo)bar&#39;, &#39;foobar&#39;)
<_sre.SRE_Match object; span=(3, 6), match=&#39;bar&#39;>
>>> print(re.search(&#39;(?<=qux)bar&#39;, &#39;foobar&#39;))
None

(?998c4a64480658e9612f23091b4c8076) 否定的向后断言

# 例子和之前的向后积极断言相反
>>> print(re.search(&#39;(?<!foo)bar&#39;, &#39;foobar&#39;))
None
>>> re.search(&#39;(?<!qux)bar&#39;, &#39;foobar&#39;)
<_sre.SRE_Match object; span=(3, 6), match=&#39;bar&#39;>

类别9:杂项元字符

(?#…) 指定注释

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

竖条或管道 ( | ) 指定要匹配的一组备选方案

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

# 结合交替、分组和任何其他元字符来实现您需要的任何复杂程度。
# (foo|bar|baz)+表示一个或多个字符串
>>> re.search(&#39;(foo|bar|baz)+&#39;, &#39;foofoofoo&#39;)
<_sre.SRE_Match object; span=(0, 9), match=&#39;foofoofoo&#39;>
>>> re.search(&#39;(foo|bar|baz)+&#39;, &#39;bazbazbazbaz&#39;)
<_sre.SRE_Match object; span=(0, 12), match=&#39;bazbazbazbaz&#39;>
>>> re.search(&#39;(foo|bar|baz)+&#39;, &#39;barbazfoo&#39;)
<_sre.SRE_Match object; span=(0, 9), match=&#39;barbazfoo&#39;>

# ([0-9]+|[a-f]+)表示一个或多个十进制数字字符的序列或一个或多个&#39;a-f&#39;字符的序列
>>> re.search(&#39;([0-9]+|[a-f]+)&#39;, &#39;456&#39;)
<_sre.SRE_Match object; span=(0, 3), match=&#39;456&#39;>
>>> re.search(&#39;([0-9]+|[a-f]+)&#39;, &#39;ffda&#39;)
<_sre.SRE_Match object; span=(0, 4), match=&#39;ffda&#39;>

以上是Python中re模块的元字符怎么使用的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文转载于:yisu.com。如有侵权,请联系admin@php.cn删除