Python 正则表达式 语法 方法

Python 正则表达式

语法

在线工具:正则表达式可视化工具正则表达式在线测试工具

特殊字符

  • .

    (点) 在默认模式,匹配除了换行的任意字符。如果指定了标签 re.DOTALL ,它将匹配包括换行符的任意字符。

  • ^

    (插入符号) 匹配字符串的开头, 并且在 re.MULTILINE模式也匹配换行后的首个符号。

  • $

    匹配字符串尾或者在字符串尾的换行符的前一个字符,在 re.MULTILINE模式下也会匹配换行符之前的文本。 foo 匹配 ‘foo’ 和 ‘foobar’,但正则表达式 foo$ 只匹配 ‘foo’。

    • 更有趣的是,在 'foo1\nfoo2\n' 中搜索 foo.$,通常匹配 ‘foo2’,但在 re.MULTILINE模式下可以匹配到 ‘foo1’;在 'foo\n' 中搜索 $ 会找到两个(空的)匹配:一个在换行符之前,一个在字符串的末尾。
  • *

    对它前面的正则式匹配0到任意次重复, 尽量多的匹配字符串。 ab* 会匹配 'a''ab',或者 'a' 后面跟随任意个 'b'。相当于{0,}

  • +

    对它前面的正则式匹配1到任意次重复。 ab+ 会匹配 'a' 后面跟随1个以上到任意个 'b',它不会匹配 'a'。相当于{1,}

  • ?

    对它前面的正则式匹配0到1次重复。 ab? 会匹配 'a' 或者 'ab'。相当于{0,1}

  • *?, +?, ??

    '*', '+',和 '?' 修饰符都是 贪婪的;它们在字符串进行尽可能多的匹配。有时候并不需要这种行为。

    • 如果正则式 <.*> 希望找到 '<a> b <c>',它将会匹配整个字符串,而不仅是 '<a>'。在修饰符之后添加 ? 将使样式以非贪婪方式或者最小方式进行匹配; 尽量的字符将会被匹配。 使用正则式 <.*?> 将会仅仅匹配 '<a>'
  • {m}

    对其之前的正则式指定匹配 m 个重复;少于 m 的话就会导致匹配失败。比如, a{6} 将匹配6个 'a' , 但是不能是5个。

  • {m,n}

    对正则式进行 mn 次匹配,在 mn 之间取尽量多。 比如,a{3,5} 将匹配 3 到 5个 'a'。忽略 m 意为指定下界为0,忽略 n 指定上界为无限次。 比如 a{4,}b 将匹配 'aaaab' 或者1000个 'a' 尾随一个 'b',但不能匹配 'aaab'。逗号不能省略,否则无法辨别修饰符应该忽略哪个边界。

  • {m,n}?

    前一个修饰符的非贪婪模式,只匹配尽量少的字符次数。比如,对于 'aaaaaa'a{3,5} 匹配 5个 'a' ,而 a{3,5}? 只匹配3个 'a'

  • \

    转义特殊字符(允许你匹配 '*', '?', 或者此类其他),或者表示一个特殊序列;特殊序列之后进行讨论。如果你没有使用原始字符串( r'raw' )来表达样式,要牢记Python也使用反斜杠作为转义序列;如果转义序列不被Python的分析器识别,反斜杠和字符才能出现在字符串中。

    如果Python可以识别这个序列,那么反斜杠就应该重复两次。这将导致理解障碍,所以高度推荐,就算是最简单的表达式,也要使用原始字符串。

  • []

    用于表示一个字符集合。在一个集合中:

    • 字符可以单独列出,比如 [amk] 匹配 'a''m', 或者 'k'

    • 可以表示字符范围,通过用 '-' 将两个字符连起来。比如 [a-z] 将匹配任何小写ASCII字符, [0-5][0-9] 将匹配从 0059 的两位数字, [0-9A-Fa-f] 将匹配任何十六进制数位。 如果 - 进行了转义 (比如 [a\-z])或者它的位置在首位或者末尾(如 [-a][a-]),它就只表示普通字符 '-'

    • 特殊字符在集合中,失去它的特殊含义。比如 [(+*)] 只会匹配这几个文法字符 '(', '+', '*', or ')'

    • 字符类如 \w 或者 \S (如下定义) 在集合内可以接受,它们可以匹配的字符由 ASCII或者 LOCALE 模式决定。

    • 不在集合范围内的字符可以通过 取反 来进行匹配。如果集合首字符是 '^' ,所有 在集合内的字符将会被匹配,比如 [^5] 将匹配所有字符,除了 '5'[^^] 将匹配所有字符,除了 '^'. ^ 如果不在集合首位,就没有特殊含义。

    • 在集合内要匹配一个字符 ']',有两种方法,要么就在它之前加上反斜杠,要么就把它放到集合首位。比如, [()[\]{}][]()[{}] 都可以匹配括号。

    • Unicode Technical Standard #18 里的嵌套集合和集合操作支持可能在未来添加。这将会改变语法,所以为了帮助这个改变,一个 FutureWarning将会在有多义的情况里被 raise,包含以下几种情况,集合由 '[' 开始,或者包含下列字符序列 '--', '&&', '~~', 和 '||'。为了避免警告,需要将它们用反斜杠转义。

  • |

    A|BAB 可以是任意正则表达式,创建一个正则表达式,匹配 A 或者 B. 任意个正则表达式可以用 '|' 连接。它也可以在组合(见下列)内使用。扫描目标字符串时, '|' 分隔开的正则样式从左到右进行匹配。当一个样式完全匹配时,这个分支就被接受。意思就是,一旦 A 匹配成功, B 就不再进行匹配,即便它能产生一个更好的匹配。或者说,'|' 操作符绝不贪婪。 如果要匹配 '|' 字符,使用 \|, 或者把它包含在字符集里,比如 [|].

  • (...)

    (组合),匹配括号内的任意正则表达式,并标识出组合的开始和结尾。匹配完成后,组合的内容可以被获取,并可以在之后用 \number 转义序列进行再次匹配,之后进行详细说明。要匹配字符 '(' 或者 ')', 用 \(\), 或者把它们包含在字符集合里: [(], [)].

  • (?…)

    这是个扩展标记法 (一个 '?' 跟随 '(' 并无含义)。 '?' 后面的第一个字符决定了这个构建采用什么样的语法。这种扩展通常并不创建新的组合; (?P<name>...) 是唯一的例外。 以下是目前支持的扩展。

\ + 字符

'\' 和一个字符组成的特殊序列在以下列出。 如果普通字符不是ASCII数位或者ASCII字母,那么正则样式将匹配第二个字符。比如,\$ 匹配字符 '$'.

  • \number

    匹配数字代表的组合。每个括号是一个组合,组合从1开始编号。

    • 比如 (.+) \1 匹配 'the the' 或者 '55 55', 但不会匹配 'thethe' (注意组合后面的空格)。这个特殊序列只能用于匹配前面99个组合。
    • 如果 number 的第一个数位是0, 或者 number 是三个八进制数,它将不会被看作是一个组合,而是八进制的数字值。在 '['']' 字符集合内,任何数字转义都被看作是字符。
  • \A

    只匹配字符串开始。

  • \b

    匹配空字符串,但只在单词开始或结尾的位置。一个单词被定义为一个单词字符的序列。

    • 注意,通常 \b 定义为 \w\W 字符之间,或者 \w 和字符串开始/结尾的边界, 意思就是 r'\bfoo\b' 匹配 'foo', 'foo.', '(foo)', 'bar foo baz' 但不匹配 'foobar' 或者 'foo3'
    • 默认情况下,Unicode字母和数字是在Unicode样式中使用的,但是可以用 ASCII标记来更改。如果 LOCALE标记被设置的话,词的边界是由当前语言区域设置决定的,\b 表示退格字符,以便与Python字符串文本兼容。
  • \B

    匹配空字符串,但 能在词的开头或者结尾。意思就是 r'py\B' 匹配 'python', 'py3', 'py2', 但不匹配 'py', 'py.', 或者 'py!'. \B\b 的取非,所以Unicode样式的词语是由Unicode字母,数字或下划线构成的,虽然可以用 ASCII标志来改变。如果使用了 LOCALE 标志,则词的边界由当前语言区域设置。

  • \d

    对于 Unicode (str) 样式:匹配任何Unicode十进制数(就是在Unicode字符目录[Nd]里的字符)。这包括了 [0-9] ,和很多其他的数字字符。如果设置了 ASCII标志,就只匹配 [0-9]

    -对于8位(bytes)样式:匹配任何十进制数,就是 [0-9]

  • \D

    匹配任何非十进制数字的字符。就是 \d 取非。 如果设置了 ASCII标志,就相当于 [^0-9]

  • \s

    • 对于 Unicode (str) 样式:匹配任何Unicode空白字符(包括 [ \t\n\r\f\v] ,还有很多其他字符,比如不同语言排版规则约定的不换行空格)。如果 ASCII 被设置,就只匹配 [ \t\n\r\f\v]

    • 对于8位(bytes)样式:匹配ASCII中的空白字符,就是 [ \t\n\r\f\v]

  • \S

    匹配任何非空白字符。就是 \s 取非。如果设置了 ASCII标志,就相当于 [^ \t\n\r\f\v]

  • \w

    对于 Unicode (str) 样式:匹配Unicode词语的字符,包含了可以构成词语的绝大部分字符,也包括数字和下划线。如果设置了 ASCII标志,就只匹配 [a-zA-Z0-9_] 。对于8位(bytes)样式:匹配ASCII字符中的数字和字母和下划线,就是 [a-zA-Z0-9_] 。如果设置了 LOCALE标记,就匹配当前语言区域的数字和字母和下划线。

  • \W

    匹配非单词字符的字符。这与 \w 正相反。如果使用了ASCII旗标,这就等价于 [^a-zA-Z0-9_]。如果使用了 LOCALE旗标,则会匹配当前区域中既非字母数字也非下划线的字符。

  • \Z

    只匹配字符串尾。

  • 绝大部分Python的标准转义字符也被正则表达式分析器支持。:

\a      \b      \f      \n
\N      \r      \t      \u
\U      \v      \x      \\

Note:

\b 被用于表示词语的边界,它只在字符集合内表示退格,比如 [\b]

'\u', '\U''\N' 转义序列只在 Unicode 模式中可被识别。 在 bytes 模式中它们会导致错误。 未知的 ASCII 字母转义序列保留在未来使用,会被当作错误来处理。

八进制转义包含为一个有限形式。如果首位数字是 0, 或者有三个八进制数位,那么就认为它是八进制转义。其他的情况,就看作是组引用。对于字符串文本,八进制转义最多有三个数位长。

元字符

元字符描述
.匹配任意单个字符,除了\n
[ ]字符种类,匹配方括号内任意字符
[^ ]否定的字符种类,匹配除了方括号里的任意字符
*匹配0到任意次重复,相当于{0,}
+匹配1到任意次重复,相当于{1,}
?匹配0到1次重复,相当于{0,1}
{n, m}对正则式进行 mn 次匹配
(xyz)字符集,匹配与xyz完全相等的字符串
|或运算,匹配符号前或符号后的字符
\转义字符,用于匹配保留字() [] {} . * + ? ^ $ \ |
^匹配字符串开始的位置
$匹配字符串结尾的位置

拓展语法

拓展语法

  • (?aiLmsux-imsx:…)

    ('a', 'i', 'L', 'm', 's', 'u', 'x' 中的0或者多个, 之后可选跟随 '-' 在后面跟随 'i' , 'm' , 's' , 'x' 中的一到多个 .) 该组匹配空字符串; 字母设置相应的标志:

    • 这些字符为表达式的其中一部分 对应一种匹配标志: re.A (只匹配ASCII), re.I(忽略大小写), re.L (语言依赖), re.M (多行), re.S(点匹配所有字符), re.U (Unicode匹配), and re.X (冗长模式)。(标记描述)
    • 'a', 'L' and 'u' 作为内联标记是相互排斥的, 所以它们不能结合在一起,或者跟随 '-' 。 当他们中的某个出现在内联组中,它就覆盖了括号组内的匹配模式。
      • 在Unicode样式中, (?a:...) 切换为 只匹配ASCII, (?u:...) 切换为Unicode匹配 (默认).
      • 在byte样式中 (?L:...) 切换为语言依赖模式, (?a:...) 切换为 只匹配ASCII (默认)。这种方式只覆盖组合内匹配,括号外的匹配模式不受影响。
  • (?P<name>…)

    (命名组合)类似正则组合,但是匹配到的子串组在外部是通过定义的 name来获取的。组合名必须是有效的Python标识符,并且每个组合名只能用一个正则表达式定义,只能定义一次。一个符号组合同样是一个数字组合,就像这个组合没有被命名一样。命名组合可以在三种上下文中引用。如果样式是 (?P<quote>['"]).*?(?P=quote) (也就是说,匹配单引号或者双引号括起来的字符串):

    引用组合 “quote” 的上下文引用方法
    在正则式自身内(?P=quote) (如示),\1
    处理匹配对象 mm.group('quote'),m.end('quote') (等)
    传递到 re.sub() 里的 repl 参数中\g<quote>,\g<1>,\1
  • (?P=name)

    反向引用一个命名组合;它匹配前面那个叫 name 的命名组中匹配到的串同样的字串。

  • (?#…)

    注释;里面的内容会被忽略。

  • (?=…)

    匹配 的内容,但是并不消费样式的内容。这个叫做 lookahead assertion(正先行断言)。比如, Isaac (?=Asimov) 匹配 'Isaac ' 只有在后面是 'Asimov' 的时候。

  • (?!…)

    匹配 不符合的情况。这个叫 negative lookahead assertion (负先行断言)。比如说, Isaac (?!Asimov) 只有后面 'Asimov' 的时候才匹配 'Isaac '

  • (?<=…)

    匹配字符串的当前位置,它的前面匹配 的内容到当前位置。这叫:positive lookbehind assertion (正后发断定)。 (?<=abc)def 会在 'abcdef' 中找到一个匹配,因为后视会往后看3个字符并检查是否包含匹配的样式。包含的匹配样式必须是定长的,意思就是 abca|b 是允许的,但是 a*a{3,4} 不可以。注意以 positive lookbehind assertions 开始的样式,如 (?<=abc)def ,并不是从 a 开始搜索,而是从 d 往回看的。你可能更加愿意使用 search() 函数,而不是 match()函数:

    >>> import re
    >>> m = re.search('(?<=abc)def', 'abcdef')
    >>> m.group(0)
    'def'
    

    这个例子搜索一个跟随在连字符后的单词:

    >>> m = re.search(r'(?<=-)\w+', 'spam-egg')
    >>> m.group(0)
    'egg'
    
  • (?<!…)

    匹配当前位置之前不是 ... 的样式。这个叫 negative lookbehind assertion (负后发断言)。类似正向后视断定,包含的样式匹配必须是定长的。由 negative lookbehind assertion 开始的样式可以从字符串搜索开始的位置进行匹配。

  • (?(id/name)yes-pattern|no-pattern)

    如果给定的 idname 存在,将会尝试匹配 yes-pattern ,否则就尝试匹配 no-patternno-pattern 可选,也可以被忽略。比如, (<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$) 是一个email样式匹配,将匹配 '<user@host.com>''user@host.com' ,但不会匹配 '<user@host.com' ,也不会匹配 'user@host.com>'

方法

应用匹配

方法 / 属性目的
match()确定正则是否从字符串的开头匹配。
search()扫描字符串,查找此正则匹配的任何位置。
findall()找到正则匹配的所有子字符串,并将它们作为列表返回。
finditer()找到正则匹配的所有子字符串,并将它们返回为一个 iterator

方法详解

  • re.search(pattern, string, flags=0)
    扫描整个string找到匹配pattern的第一个位置,并返回一个相应的 匹配对象。如果没有匹配,就返回一个 None ; 注意这和找到一个零长度匹配是不同的。
  • re.match(pattern, string, flags=0)
    如果 string开始的0或者多个字符匹配到了正则表达式pattern,就返回一个相应的 匹配对象 。 如果没有匹配,就返回 None;注意它跟零长度匹配是不同的。
>>> re.match("c", "abcdef")    # No match
>>> re.search("c", "abcdef")   # Match
<re.Match object; span=(2, 3), match='c'>

search()中,可以用 '^' 作为开始来限制匹配到字符串的首位

>>> re.match("c", "abcdef")    # No match
>>> re.search("^c", "abcdef")  # No match
>>> re.search("^a", "abcdef")  # Match
<re.Match object; span=(0, 1), match='a'>

注意 MULTILINE多行模式中函数 match()只匹配字符串的开始,但使用search()和以 '^' 开始的正则表达式会匹配每行的开始

>>> re.match('X', 'A\nB\nX', re.MULTILINE)  # No match
>>> re.search('^X', 'A\nB\nX', re.MULTILINE)  # Match
<re.Match object; span=(4, 5), match='X'>
  • re.findall(pattern, string, flags=0)
    string返回一个不重复的 pattern的匹配列表, string从左到右进行扫描,匹配按找到的顺序返回。如果样式里存在一到多个组,就返回一个组合列表;就是一个元组的列表(如果样式里有超过一个组合的话)。空匹配也会包含在结果里。

  • re.finditer(pattern, string, flags=0)
    patternstring里所有的非重复匹配,返回为一个迭代器 iterator保存了 匹配对象 。 string从左到右扫描,匹配按顺序排列。空匹配也包含在结果里。

    在 3.7 版更改: 非空匹配现在可以在前一个空匹配之后出现了。

  • re.fullmatch(pattern, string, flags=0)
    如果整个 string匹配到正则表达式pattern,就返回一个相应的 匹配对象 。 否则就返回一个 None;注意这跟零长度匹配是不同的。

>>> re.fullmatch(r'[1-9]*', "323", flags=0)
<re.Match object; span=(0, 3), match='323'>
>>> re.fullmatch(r'[1-9]*', "a323", flags=0)  # No match
  • re.split(pattern, string, maxsplit=0, flags=0)
    pattern分开 string。 如果在 pattern中捕获到括号(),那么所有的组里的文字也会包含在列表里。如果 maxsplit非零, 最多进行 maxsplit次分隔, 剩下的字符全部返回到列表的最后一个元素。
>>> re.split(r'\W+', 'Words, words, words.') # 匹配任何非字母与数字字符
['Words', 'words', 'words', '']
>>> re.split(r'(\W+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>> re.split(r'\W+', 'Words, words, words.', 1)
['Words', 'words, words.']
>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)
['0', '3', '9']

如果分隔符里有捕获组合,并且匹配到字符串的开始,那么结果将会以一个空字符串开始。对于结尾也是一样

>>> re.split(r'(\W+)', '...words, words...') # 匹配任何非字母与数字字符
['', '...', 'words', ', ', 'words', '...', '']

这样的话,分隔组将会出现在结果列表中同样的位置。

样式的空匹配仅在与前一个空匹配不相邻时才会拆分字符串。

>>> re.split(r'\b', 'Words, words, words.')  # 开始或结尾处匹配空字符串
['', 'Words', ', ', 'words', ', ', 'words', '.']
>>> re.split(r'\W*', '...words...') # 匹配任何非字母与数字字符
['', '', 'w', 'o', 'r', 'd', 's', '', '']
>>> re.split(r'(\W*)', '...words...') 
['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', '']
  • re.sub(pattern, repl, string, count=0, flags=0)
    返回通过使用 repl 替换在 string最左边非重叠出现的 pattern而获得的字符串。 如果样式没有找到,则不加改变地返回 string

  • repl可以是字符串或函数;如为字符串,则其中任何反斜杠转义序列都会被处理。 也就是说,\n 会被转换为一个换行符,\r 会被转换为一个回车附,依此类推。 未知的 ASCII 字符转义序列保留在未来使用,会被当作错误来处理。 其他未知转义序列例如\& 会保持原样。 向后引用像是\6 会用样式中第 6 组所匹配到的子字符串来替换。 例如:

>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):', 
           		# 匹配 'def 函数名():', 函数名送进组
           r'static PyObject*\npy_\1(void)\n{',
           		# 使用匹配的第一组替换\1
           'def myfunc():')
'static PyObject*\npy_myfunc(void)\n{'
  • re.subn(pattern, repl, string, count=0, flags=0)

行为与 sub()相同,但是返回一个元组 (字符串, 替换次数).

  • re.escape(pattern)

转义 pattern 中的特殊字符。如果你想对任意可能包含正则表达式元字符的文本字符串进行匹配,它就是有用的。比如

>>> print(re.escape('http://www.python.org'))
http://www\.python\.org

>>> legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:"
>>> print('[%s]+' % re.escape(legal_chars))
[abcdefghijklmnopqrstuvwxyz0123456789!\#\$%\&'\*\+\-\.\^_`\|\~:]+

>>> operators = ['+', '-', '*', '/', '**']
>>> print('|'.join(map(re.escape, sorted(operators, reverse=True))))
/|\-|\+|\*\*|\*

这个函数不能被用于sub()subn()的替换字符串,只有反斜杠应该被转义。 例如:

>>> digits_re = r'\d+'
>>> sample = '/usr/sbin/sendmail - 0 errors, 12 warnings'
>>> print(re.sub(digits_re, digits_re.replace('\\', r'\\'), sample))
/usr/sbin/sendmail - \d+ errors, \d+ warnings
  • re.compile(pattern, flags=0)

将正则表达式的pattern编译为一个 正则表达式对象,可以用于匹配,通过这个对象的方法 match(), search()以及其他如下描述。

这个表达式的行为可以通过指定 flags 的值来改变。值可以是以下任意变量,可以通过位的OR操作来结合( | 操作符)。

prog = re.compile(pattern)
result = prog.match(string)
# 等价于 ||
result = re.match(pattern, string)

如果需要多次使用这个正则表达式的话,使用 re.compile()和保存这个正则对象以便复用,可以让程序更加高效。

注解:通过 re.compile()编译后的样式,和模块级的函数会被缓存, 所以少数的正则表达式使用无需考虑编译的问题。

flags编译标志

flags

flags简介
flags含义
re.ASCII,re.A让 转义字符(\w,\W,\b,\B,\d,\D,\s,\S)只匹配ASCII字符
re.IGNORECASE,re.I匹配的时候不区分大小写
re.LOCALE,re.L支持当前的语言(区域)设置
re.MULTILINE,re.M多行匹配,影响^$
re.DOTALL,re.S使得(.)匹配任何符号,包括换行符
re.VERBOSE,re.X启用详细的正则表达式
re.DEBUG显示编译时的debug信息,没有内联标记
flags详解
  • re.ASCII,re.A

    \w, \W, \b, \B, \d, \D, \s\S 只匹配ASCII,而不是Unicode。这只对Unicode样式有效,会被byte样式忽略。相当于前面语法中的内联标志 (?a) 。注意,为了保持向后兼容, re.U 标记依然存在(还有他的同义 re.UNICODE 和嵌入形式 (?u) ) , 但是这些在 Python 3 是冗余的,因为默认字符串已经是Unicode了(并且Unicode匹配不允许byte出现)。

  • re.DEBUG

    显示编译时的debug信息,没有内联标记。

  • re.IGNORECASE,re.I

    进行忽略大小写匹配;表达式如 [A-Z] 也会匹配小写字符。Unicode匹配(比如 Ü 匹配 ü)同样有用,除非设置了 re.ASCII标记来禁用非ASCII匹配。当前语言区域不会改变这个标记,除非设置了 re.LOCALE标记。这个相当于内联标记 (?i)

    Note:当设置了 IGNORECASE 标记,搜索Unicode样式 [a-z][A-Z] 的结合时,它将会匹配52个ASCII字符和4个额外的非ASCII字符: ‘İ’ (U+0130, 拉丁大写的 I 带个点在上面),‘ı’ (U+0131, 拉丁小写没有点的 I ),‘ſ’ (U+017F, 拉丁小写长 s) 和 ‘K’ (U+212A, 开尔文符号)。如果使用 ASCII标记,就只匹配 ‘a’ 到 ‘z’ 和 ‘A’ 到 ‘Z’

  • re.LOCALE,re.L

    由当前语言区域决定 \w, \W, \b, \B 和大小写敏感匹配。这个标记只能对byte样式有效。这个标记不推荐使用,因为语言区域机制很不可靠,它一次只能处理一个 "习惯”,而且只对8位字节有效。Unicode匹配在Python 3 里默认启用,并可以处理不同语言。 这个对应内联标记 (?L)

  • re.MULTILINE,re.M

    设置以后,样式字符 '^' 匹配字符串的开始,和每一行的开始(换行符后面紧跟的符号);样式字符 '$' 匹配字符串尾,和每一行的结尾(换行符前面那个符号)。默认情况下,’^’ 匹配字符串头,'$' 匹配字符串尾。对应内联标记 (?m)

  • re.DOTALL,re.S

    '.' 特殊字符匹配任何字符,包括换行符;如果没有这个标记,'.' 就匹配 除了 换行符的其他任意字符。对应内联标记 (?s)

  • re.VERBOSE,re.X

    这个标记允许你编写更具可读性更友好的正则表达式。通过分段和添加注释。空白符号会被忽略,除非在一个字符集合当中或者由反斜杠转义,或者在 *?, (?: or (?P<…> 分组之内。当一个行内有 # 不在字符集和转义序列,那么它之后的所有字符都是注释。

编译后方法

编译后的正则表达式支持以下方法

  • Pattern.search(string[, pos[, endpos]])

    扫描整个 string 寻找第一个匹配的位置, 并返回一个相应的匹配对象。如果没有匹配,就返回 None ;注意它和零长度匹配是不同的。

    • 可选的第二个参数 pos 给出了字符串中开始搜索的位置索引;默认为 0,它不完全等价于字符串切片; '^' 样式字符匹配字符串真正的开头,和换行符后面的第一个字符,但不会匹配索引规定开始的位置。

    • 可选参数 endpos 限定了字符串搜索的结束;它假定字符串长度到 endpos , 所以只有从 posendpos - 1 的字符会被匹配。如果 endpos 小于 pos,就不会有匹配产生;另外,如果 rx 是一个编译后的正则对象, rx.search(string, 0, 50) 等价于 rx.search(string[:50], 0)

    >>> pattern = re.compile("d")
    >>> pattern.search("dog")     # Match at index 0
    <re.Match object; span=(0, 1), match='d'>
    >>> pattern.search("dog", 1)  # No match; search doesn't include the "d"
    
  • Pattern.match(string[, pos[, endpos]])

    如果 string开始位置 能够找到这个正则样式的任意个匹配,就返回一个相应的匹配对象。如果不匹配,就返回 None ;注意它与零长度匹配是不同的。

    可选参数 posendpossearch() 含义相同。

    >>> pattern = re.compile("d")
    >>> pattern.search("dog")     # Match at index 0
    <re.Match object; span=(0, 1), match='d'>
    >>> pattern.search("dog", 1)  # No match; search doesn't include the "d"
    
  • Pattern.fullmatch(string[, pos[, endpos]])

    如果整个 string 匹配这个正则表达式,就返回一个相应的匹配对象。 否则就返回 None ; 注意跟零长度匹配是不同的。

    可选参数 posendpossearch() 含义相同。

    >>> pattern = re.compile("o[gh]")
    >>> pattern.fullmatch("dog")      # No match as "o" is not at the start of "dog".
    >>> pattern.fullmatch("ogre")     # No match as not the full string matches.
    >>> pattern.fullmatch("doggie", 1, 3)   # Matches within given limits.
    <re.Match object; span=(1, 3), match='og'>
    
  • Pattern.split(string, maxsplit=0)

    等价于 split()函数,使用了编译后的样式。

  • Pattern.findall(string[, pos[, endpos]])

    类似函数 findall(), 使用了编译后样式,但也可以接收可选参数 posendpos ,限制搜索范围,就像 search())。

  • Pattern.finditer(string[, pos[, endpos]])

    类似函数 finditer(), 使用了编译后样式,但也可以接收可选参数 posendpos ,限制搜索范围,就像 search()

  • Pattern.sub(repl, string, count=0)

    等价于 sub()函数,使用了编译后的样式。

  • Pattern.subn(repl, string, count=0)

    等价于 subn()函数,使用了编译后的样式。

  • Pattern.flags

    正则匹配标记。这是可以传递给 compile()的参数,任何 (?…) 内联标记,隐性标记比如 UNICODE 的结合。

  • Pattern.groups

    捕获到的模式串中组的数量。

  • Pattern.groupindex

    映射由 (?P<id>) 定义的命名符号组合和数字组合的字典。如果没有符号组,那字典就是空的。

  • Pattern.pattern

    编译对象的原始样式字符串。

匹配对象方法

  • Match.expand(template)

    template 进行反斜杠转义替换并且返回,就像 sub()方法中一样。转义如同 \n 被转换成合适的字符,数字引用(\1, \2)和命名组合(\g<1>, \g<name>) 替换为相应组合的内容。在 3.5 版更改: 不匹配的组合替换为空字符串。

  • Match.group([group1, ])

    返回一个或者多个匹配的子组。如果只有一个参数,结果就是一个字符串,如果有多个参数,结果就是一个元组(每个参数对应一个项),如果没有参数,组1默认到0(整个匹配都被返回)。 如果一个组N 参数值为 0,相应的返回值就是整个匹配字符串;如果它是一个范围 [1…99],结果就是相应的括号组字符串。如果一个组号是负数,或者大于样式中定义的组数,一个 IndexError索引错误就 raise。如果一个组包含在样式的一部分,并被匹配多次,就返回最后一个匹配。:

    >>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
    >>> m.group(0)       # 整个匹配
    'Isaac Newton'
    >>> m.group(1)       # 第一个带括号的子组
    'Isaac'
    >>> m.group(2)       # 第二个带括号的子组
    'Newton'
    >>> m.group(1, 2)    # 多个参数给我们一个元组
    ('Isaac', 'Newton')
    

    如果正则表达式使用了 (?P<name>…) 语法, groupN 参数就也可能是命名组合的名字。如果一个字符串参数在样式中未定义为组合名,一个 IndexErrorraise

    一个相对复杂的例子

    >>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
    >>> m.group('first_name')
    'Malcolm'
    >>> m.group('last_name')
    'Reynolds'
    

    命名组合同样可以通过索引值引用

    >>> m.group(1)
    'Malcolm'
    >>> m.group(2)
    'Reynolds'
    

    如果一个组匹配成功多次,就只返回最后一个匹配

    >>> m = re.match(r"(..)+", "a1b2c3")  # 匹配 3 次
    >>> m.group(1)                        # 只返回最后一个匹配
    'c3'
    
  • .Match.__getitem__(g)

    这个等价于 m.group(g)。这允许更方便的引用一个匹配

    >>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
    >>> m[0]       # 整个匹配
    'Isaac Newton'
    >>> m[1]       # 第一个带括号的子组
    'Isaac'
    >>> m[2]       # 第二个带括号的子组
    'Newton'
    
  • Match.groups(default=None)

    返回一个元组,包含所有匹配的子组,在样式中出现的从1到任意多的组合。 default 参数用于不参与匹配的情况,默认为 None。例如:

    >>> m = re.match(r"(\d+)\.(\d+)", "24.1632")
    >>> m.groups()
    ('24', '1632')
    

    如果我们使小数点可选,那么不是所有的组都会参与到匹配当中。这些组合默认会返回一个 None ,除非指定了 default 参数。

    >>> m = re.match(r"(\d+)\.?(\d+)?", "24")
    >>> m.groups()      # 第二组默认为无。
    ('24', None)
    >>> m.groups('0')   # 现在,第二组默认为 '0'
    ('24', '0')
    
  • Match.groupdict(default=None)

    返回一个字典,包含了所有的 命名 子组。key就是组名。 default 参数用于不参与匹配的组合;默认为 None。 例如

    >>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
    >>> m.groupdict()
    {'first_name': 'Malcolm', 'last_name': 'Reynolds'}
    
  • Match.start([group])

  • Match.end([group])

    返回 group 匹配到的字串的开始和结束标号。group 默认为0(意思是整个匹配的子串)。如果 group 存在,但未产生匹配,就返回 -1 。对于一个匹配对象 m, 和一个未参与匹配的组 g ,组 g (等价于 m.group(g))产生的匹配是

    m.string[m.start(g):m.end(g)]
    

    注意 m.start(group) 将会等于 m.end(group) ,如果 group 匹配一个空字符串的话。比如,在 m = re.search('b(c?)', 'cba') 之后,m.start(0) 为 1, m.end(0) 为 2, m.start(1)m.end(1) 都是 2, m.start(2) raise 一个 IndexError 例外。

    这个例子会从email地址中移除掉 remove_this

    >>> email = "tony@tiremove_thisger.net"
    >>> m = re.search("remove_this", email)
    >>> email[:m.start()] + email[m.end():]
    'tony@tiger.net'
    
  • Match.span([group])

    对于一个匹配 m , 返回一个二元组 (m.start(group), m.end(group)) 。 注意如果 group 没有在这个匹配中,就返回 (-1, -1)group 默认为0,就是整个匹配。

  • Match.pos

    pos 的值,会传递给 search()match()的方法 a 正则对象。这个是正则引擎开始在字符串搜索一个匹配的索引位置。

  • Match.endpos

    endpos 的值,会传递给 search()match()的方法 a 正则对象 。这个是正则引擎停止在字符串搜索一个匹配的索引位置。

  • Match.lastindex

    捕获组的最后一个匹配的整数索引值,或者 None 如果没有匹配产生的话。比如,对于字符串 'ab',表达式 (a)b, ((a)(b)), 和 ((ab)) 将得到 lastindex == 1 , 而 (a)(b) 会得到 lastindex == 2

  • Match.lastgroup

    最后一个匹配的命名组名字,或者 None 如果没有产生匹配的话。

  • Match.re

    返回产生这个实例的 正则对象, 这个实例是由 正则对象的 match()search()方法产生的。

  • Match.string

    传递到 match()search()的字符串。

posted @ 2021-07-29 00:15  SKPrimin  阅读(97)  评论(0编辑  收藏  举报