>  기사  >  백엔드 개발  >  Python에서 re 모듈의 메타 문자를 사용하는 방법

Python에서 re 모듈의 메타 문자를 사용하는 방법

WBOY
WBOY앞으로
2023-06-02 20:19:351558검색

메타 문자는 정규식에서 특별한 의미를 갖는 특수 문자이며, 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 모듈의 메타 문자를 사용하는 방법

다음 목록은 메타문자에 대한 설명입니다. 이해가 되지 않는다면 아래 예시로 건너뛰세요.

+는 이전 하위 표현식과 1회 이상 일치합니다. 예를 들어 ‘zo+’는 "zo" 및 "zoo"와 일치하지만 "z"와는 일치하지 않습니다.+는 {1,}과 같습니다. B
Character Description
다음 문자를 특수 문자, 리터럴 문자, 역참조 또는 8진수 이스케이프 문자로 표시합니다. 예를 들어 ‘n’은 문자 "n"과 일치합니다. ‘n’은 개행 문자와 일치합니다. 시퀀스 ‘’는 ""와 일치하고 "("는 "("와 일치합니다.
^ 는 입력 문자열의 시작 부분과 일치합니다. RegExp 개체의 Multiline 속성이 설정된 경우 ^는 ‘n&rsquo와도 일치합니다. ; 또는 ‘r’ 뒤의 위치는 입력 문자열의 끝과 일치합니다. RegExp 개체의 Multiline 속성이 설정된 경우 $는 ‘n’과 일치합니다. 예를 들어, zo*는 "z" 및 "zoo"와 일치할 수 있습니다. *는 {0,}와 동일합니다.
? 이전 하위 표현식과 0번 또는 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
? 문자가 다른 제한자(*, +, ?, {n}, {n,}, {n,m}) 바로 뒤에 오면 일치 패턴은 탐욕스럽지 않습니다. Non-greedy 모드는 검색된 문자열을 최대한 적게 일치시키는 반면, 기본 Greedy 모드는 검색된 문자열을 최대한 많이 일치시킵니다. 예를 들어, 문자열 "oooo"의 경우 ‘o+?’는 단일 "o"와 일치하고 ‘o+’는 모든 ‘o’와 일치합니다.
. 은 개행(n, r)을 제외한 모든 단일 문자와 일치합니다. ‘n’을 포함한 모든 문자를 일치시키려면 "(.
x|y 와 같은 것을 사용하여 x 또는 y와 일치시키십시오. 예를 들어 'z
[xyz] 문자 세트와 일치하십시오. 예를 들어 ‘[abc]’는 "plain"에서 ‘a’와 일치할 수 있습니다.
[^xyz] 는 모든 음수 문자와 일치합니다. ’는 "plain"의 ’p’, ‘i’, ‘n’과 일치할 수 있습니다. 예를 들어 ‘[a-z]’ ‘a’부터 ‘z’
[^a-z] 지정된 범위에 없는 모든 문자와 일치합니다. 예를 들어 ‘[^a-z]’
b 범위는 단어 경계와 일치합니다. 예를 들어 ‘erb’ ; "never"에서는
이 아닙니다. "erB"는 "verb"에서 "er"와 일치하지 않습니다. cx 는 x로 지정된 제어 문자와 일치합니다. 예를 들어, cM은 Control-M 또는 캐리지 리턴 문자와 일치합니다. x의 값은 A-Z 또는 a-z 중 하나여야 합니다. 그렇지 않으면 c는 리터럴 ‘c’
d 은 [0-9]와 동일합니다.
D 은 x0c 및 cJ와 동일합니다. x0d 및 cM과 동일합니다. 공백, 탭, 양식 피드 등을 포함합니다.
S 과 동일합니다. 공백이 아닌 문자와 일치합니다. [^ fnrtv]와 동일합니다.
t 은 탭 문자와 일치합니다. x09 및 cI와 동일합니다.
v 은 세로 탭 문자와 일치합니다. x0b 및 cK와 동일합니다.
w 문자, 숫자, 밑줄을 일치시킵니다. '[A-Za-z0-9_]'와 동일합니다.
W 문자가 아닌 숫자, 밑줄과 일치합니다. ‘[^A-Za-z0-9_]’와 동일합니다.
xn 은 n과 일치합니다. 여기서 n은 16진수 이스케이프 값입니다. 16진수 이스케이프 값은 정확히 두 자리 길이여야 합니다. 예를 들어 ‘x41’은 "A"와 일치합니다. ‘x041’은 ‘x04’正则表达式中可以使用 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]匹配任何单个&#39;a&#39;、&#39;r&#39;、&#39;t&#39;或&#39;z&#39;字符
# ba[artz]同时匹配&#39;bar&#39;and &#39;baz&#39;(也将匹配&#39;baa&#39;and &#39;bat&#39;)。
>>> re.search(&#39;ba[artz]&#39;, &#39;foobarqux&#39;)
<_sre.SRE_Match object; span=(3, 6), match=&#39;bar&#39;>
>>> re.search(&#39;ba[artz]&#39;, &#39;foobazqux&#39;)
<_sre.SRE_Match object; span=(3, 6), match=&#39;baz&#39;>

匹配和[a-z]之间的任何小写字母字符。

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

匹配和[0-9]之间任何数字字符。

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

[0-9a-fA-F]匹配任何十六进制数字字符。

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

[^0-9]匹配任何不是数字的字符开头的字符。

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

如果一个^字符出现在字符类中但不是第一个字符则无结果。

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

可以通过用连字符分隔字符来指定字符类中的字符范围,可以将其作为第一个或最后一个字符放置,或者使用反斜杠 ( \ ) 对其进行转义。

# 直接查找符号
>>> re.search(&#39;[-abc]&#39;, &#39;123-456&#39;)
<_sre.SRE_Match object; span=(3, 4), match=&#39;-&#39;>
>>> re.search(&#39;[abc-]&#39;, &#39;123-456&#39;)
<_sre.SRE_Match object; span=(3, 4), match=&#39;-&#39;>
>>> re.search(&#39;[ab\-c]&#39;, &#39;123-456&#39;)
<_sre.SRE_Match object; span=(3, 4), match=&#39;-&#39;>


# 查找转义符号
>>> re.search(&#39;[]]&#39;, &#39;foo[1]&#39;)
<_sre.SRE_Match object; span=(5, 6), match=&#39;]&#39;>
>>> re.search(&#39;[ab\]cd]&#39;, &#39;foo[1]&#39;)
<_sre.SRE_Match object; span=(5, 6), match=&#39;]&#39;>


# [ ] 内的元字符失去意义转义成字符处理
>>> re.search(&#39;[)*+|]&#39;, &#39;123*456&#39;)
<_sre.SRE_Match object; span=(3, 4), match=&#39;*&#39;>
>>> re.search(&#39;[)*+|]&#39;, &#39;123+456&#39;)
<_sre.SRE_Match object; span=(3, 4), match=&#39;+&#39;>

点 ( . ) 通配符

匹配除换行符以外的任何单个字符。

>>> re.search(&#39;foo.bar&#39;, &#39;fooxbar&#39;)
<_sre.SRE_Match object; span=(0, 7), match=&#39;fooxbar&#39;>
>>> print(re.search(&#39;foo.bar&#39;, &#39;foobar&#39;))
None
>>> print(re.search(&#39;foo.bar&#39;, &#39;foo\nbar&#39;))
None
>>> print(re.search(&#39;foo.bar&#39;, &#39;foosbar&#39;))
<_sre.SRE_Match object; span=(0, 7), match=&#39;foosbar&#39;>

\w 和 \W 单词字符匹配

\w匹配任何字母数字字符,单词字符是大写和小写字母、数字和下划线 ( _) 字符。

\w 等于 [a-zA-Z0-9_] 。

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

\W是相反的。它匹配任何非单词字符。

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

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

\d 和 \D 字符十进制数字匹配

\d匹配任何十进制数字字符,等价于[0-9]。

>>> re.search(&#39;\d&#39;, &#39;abc4def&#39;)
<_sre.SRE_Match object; span=(3, 4), match=&#39;4&#39;>

\D匹配任何不是十进制数字的字符,等价于[^0-9]。

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

\s 和 \S 字符空格匹配

\s匹配任何空白字符,同时也匹配换行符。

>>> re.search(&#39;\s&#39;, &#39;foo\nbar baz&#39;)
<_sre.SRE_Match object; span=(3, 4), match=&#39;\n&#39;>

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

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

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

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

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

>>> re.search(&#39;[\d\w\s]&#39;, &#39;---3---&#39;)
<_sre.SRE_Match object; span=(3, 4), match=&#39;3&#39;>
>>> re.search(&#39;[\d\w\s]&#39;, &#39;---a---&#39;)
<_sre.SRE_Match object; span=(3, 4), match=&#39;a&#39;>
>>> re.search(&#39;[\d\w\s]&#39;, &#39;--- ---&#39;)
<_sre.SRE_Match object; span=(3, 4), match=&#39; &#39;>

# 由于\w包含\d,相同的字符类也可以表示为略短[\w\s]
>>> re.search(&#39;[\w\s]&#39;, &#39;---a---&#39;)
<_sre.SRE_Match object; span=(3, 4), match=&#39;a&#39;>
>>> re.search(&#39;[\w\s]&#39;, &#39;---a---&#39;)
<_sre.SRE_Match object; span=(3, 4), match=&#39;a&#39;>
>>> re.search(&#39;[\w\s]&#39;, &#39;--- ---&#39;)
<_sre.SRE_Match object; span=(3, 4), match=&#39; &#39;>

类别2:转义元字符

反斜杠 ( \ ) 转义元字符

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

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

>>> re.search(&#39;\.&#39;, &#39;foo.bar&#39;) # 非通配符
<_sre.SRE_Match object; span=(3, 4), match=&#39;.&#39;>

>>> re.search(r&#39;\\&#39;, &#39;foo\bar&#39;)
<_sre.SRE_Match object; span=(3, 4), match=&#39;\\&#39;>

类别3:锚点

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

^ 和 \A 字符串的开头匹配项

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

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

$ 和\Z 字符串的结尾匹配项

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

>>> re.search(&#39;bar\Z&#39;, &#39;foobar&#39;)
<_sre.SRE_Match object; span=(3, 6), match=&#39;bar&#39;>
>>> print(re.search(&#39;bar\Z&#39;, &#39;barfoo&#39;))
None

# 特殊$也在搜索字符串末尾的单个换行符之前匹配
>>> re.search(&#39;bar$&#39;, &#39;foobar\n&#39;)
<_sre.SRE_Match object; span=(3, 6), match=&#39;bar&#39;>

\b 和 \B 单词匹配

\b 必须在单词的开头或结尾。

# 单词开头
>>> re.search(r&#39;\bbar&#39;, &#39;foo bar&#39;)
<_sre.SRE_Match object; span=(4, 7), match=&#39;bar&#39;>
>>> re.search(r&#39;\bbar&#39;, &#39;foo.bar&#39;)
<_sre.SRE_Match object; span=(4, 7), match=&#39;bar&#39;>
>>> print(re.search(r&#39;\bbar&#39;, &#39;foobar&#39;))
None

# 单词结尾
>>> re.search(r&#39;foo\b&#39;, &#39;foo bar&#39;)
<_sre.SRE_Match object; span=(0, 3), match=&#39;foo&#39;>
>>> re.search(r&#39;foo\b&#39;, &#39;foo.bar&#39;)
<_sre.SRE_Match object; span=(0, 3), match=&#39;foo&#39;>
>>> print(re.search(r&#39;foo\b&#39;, &#39;foobar&#39;))
None


# 单词居中
>>> re.search(r&#39;\bbar\b&#39;, &#39;foo bar baz&#39;)
<_sre.SRE_Match object; span=(4, 7), match=&#39;bar&#39;>
>>> re.search(r&#39;\bbar\b&#39;, &#39;foo(bar)baz&#39;)
<_sre.SRE_Match object; span=(4, 7), match=&#39;bar&#39;>
>>> print(re.search(r&#39;\bbar\b&#39;, &#39;foobarbaz&#39;))
None

\B 不能在单词的开头或结尾。

>>> print(re.search(r&#39;\Bfoo\B&#39;, &#39;foo&#39;))
None
>>> print(re.search(r&#39;\Bfoo\B&#39;, &#39;.foo.&#39;))
None
>>> re.search(r&#39;\Bfoo\B&#39;, &#39;barfoobaz&#39;)
<_sre.SRE_Match object; span=(3, 6), match=&#39;foo&#39;>

类别4:量词

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

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

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

匹配2个字符中全部的内容。

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

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

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

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

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

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

加问号则表示为最小长度匹配的懒惰模式。

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

# .*全匹配贪婪模式
>>> re.search(&#39;<.*>&#39;, &#39;%<foo> <bar> <baz>%&#39;)
<_sre.SRE_Match object; span=(1, 18), match=&#39;<foo> <bar> <baz>&#39;>
# *? 前一个字符0次或无限次扩展,最小匹配
>>> re.search(&#39;<.*?>&#39;, &#39;%<foo> <bar> <baz>%&#39;)
<_sre.SRE_Match object; span=(1, 6), match=&#39;<foo>&#39;>
# .+ 前一个字符1次或无限次扩展,最小匹配
>>> re.search(&#39;<.+>&#39;, &#39;%<foo> <bar> <baz>%&#39;)
<_sre.SRE_Match object; span=(1, 18), match=&#39;<foo> <bar> <baz>&#39;>
# .+? 前一个字符1次或无限次扩展,最小匹配
>>> re.search(&#39;<.+?>&#39;, &#39;%<foo> <bar> <baz>%&#39;)
<_sre.SRE_Match object; span=(1, 6), match=&#39;<foo>&#39;>

# ? 匹配懒惰模式
>>> re.search(&#39;ba?&#39;, &#39;baaaa&#39;)
<_sre.SRE_Match object; span=(0, 2), match=&#39;ba&#39;>
# ?? 前一个字符0次或1次扩展,最小匹配
>>> re.search(&#39;ba??&#39;, &#39;baaaa&#39;)
<_sre.SRE_Match object; span=(0, 1), match=&#39;b&#39;>

{m} 完全匹配m次前面元字符的正则表达式。

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

{m,n} 匹配前面正则表达式的任意数量的重复从m到n次

>>> for i in range(1, 6):
...     s = f"x{&#39;-&#39; * i}x"
...     print(f&#39;{i}  {s:10}&#39;, re.search(&#39;x-{2,4}x&#39;, s))
...
1  x-x        None
2  x--x       <_sre.SRE_Match object; span=(0, 4), match=&#39;x--x&#39;>
3  x---x      <_sre.SRE_Match object; span=(0, 5), match=&#39;x---x&#39;>
4  x----x     <_sre.SRE_Match object; span=(0, 6), match=&#39;x----x&#39;>
5  x-----x    None
正则表达式 匹配说明 相同语法
{,n} 任何小于或等于的重复次数n {0,n}
{m,} 任何大于或等于的重复次数m ----
{,} 任意次数的重复 {0,} , *
>>> 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 中的正则表达式分解为子表达式或组。

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

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

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

# 括号中的正则表达式仅匹配括号的内容
>>> 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()

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

>>> 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(, , …)

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

>>> 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:反向引用

\ 匹配连续相同字符

>>> 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:其他分组结构

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

>>> 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=) 匹配先前捕获名的内容

>>> 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;

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

>>> 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;

指定条件匹配

(?()|)

(?()|)

# ^(###)?表示搜索字符串可选地以 . 开头&#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)

(?=) 积极前瞻断言

# 断言正则表达式解析器当前位置之后的内容必须匹配
# 前瞻断言(?=[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;

(?!) 否定的前瞻断言

# 例子和之前的前瞻积极断言相反
>>> 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;>

(?) 积极的后向断言

# 断言正则表达式解析器当前位置之前的内容匹配
# 断言指定&#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

(?) 否定的向后断言

# 例子和之前的向后积极断言相反
>>> 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으로 문의하시기 바랍니다. 삭제