正则表达式语法
正则表达式 (或 RE) 指定一组字符串匹配它;在此模块中的功能让您检查一下,如果一个特定的字符串匹配给定的正则表达式 (或给定的正则表达式匹配特定的字符串,可归结为同一件事)。
正则表达式可以连接到形式新的正则表达式; 如果A 和 B 两个都是正则表达式, 那么 AB i也是正则表达式。
本模块提供了类似于那些在 Perl 中找到的正则表达式匹配操作。
两个模式和字符串被搜索可以是Unicode字符串以及8位串。然而,Unicode字符串和8位串不能混用:也就是说,你不能匹配一个Unicode字符串用字节模式,反之亦然; 类似地,要求一个取代时,替换字符串必须是同一类型的图案和搜索字符串两者。
正则表达式用反斜杠字符('\'
)来表示特殊格式或允许在不调用它们的特殊含义要使用特殊字符。这与碰撞为字符串文字相同的目的相同的字符Python的使用; 例如,匹配一个反斜杠,人们可能不得不写'\\\\'
的模式字符串,因为正则表达式必须是\\
,而且每个反斜杠必须表示为\\
一个普通的Python字符串里。
解决的办法是使用Python的raw字符串表示的正则表达式模式; 反斜杠不会以任何特殊的方式在字符串字面处理前缀'r'
。因此r"\n"
是一个包含两个字符'\'
和'n'
,而"\n"
是包含一个换行符一个一个字符的字符串。通常的模式将在Python代码使用这种原始字符串表示法表示。
需要注意的是大多数的正则表达式的操作可作为模块级的功能和方法是很重要的已编译的正则表达式。该功能是不要求你先编译一个正则表达式对象,但错过了一些微调参数快捷键。
正则表达式可以包含特殊和普通字符。最普通的字符,如 'A'
,'a'
,或 '0'
,是最简单的正则表达式;他们只是与自己相匹配。You can concatenate ordinary characters, so last
matches the string 'last'
. (In the rest of this section, we’ll write RE’s in this special style
, usually without quotes, and strings to be matched 'in single quotes'
.)
某些字符,如'|'
或'('
,是特殊的。特殊字符不是代表的普通字符类,或会影响他们周围的正则表达式解释。正则表达式模式的字符串可能不包含空字节,但可使用指定空字节\number
符号如'\x00'
。
的特殊字符是:
'.'
- (Dot.) 在默认模式下,匹配除换行符之外的任何字符。如果
DOTALL
标志被指定时,匹配任何字符包括换行符。 '^'
- (Caret.) 从字符串的开始匹配, 在
MULTILINE
模式下每个换行符后面立即开始匹配。 '$'
- 匹配字符串的结尾或只是之前换行符结尾的字符串,并在
多行
模式下也匹配在换行符之前。foo
matches both ‘foo’ and ‘foobar’, while the regular expressionfoo$
matches only ‘foo’. More interestingly, searching forfoo.$
in'foo1\nfoo2\n'
matches ‘foo2’ normally, but ‘foo1’ inMULTILINE
mode; searching for a single$
in'foo\n'
will find two (empty) matches: one just before the newline, and one at the end of the string. '*'
- 原因形成的再匹配0或多次重复前面的RE,因为许多重复的是可能的。
ab*
将匹配'a','AB'或'a'后跟任意数目的'B的。 '+'
- 使所得RE以匹配前面的RE 1以上重复。
ab+
将匹配'a'后跟任何非零数字的'B的; 它不会匹配只是'一'。 '?'
- 使所得RE以匹配前面的RE 0或1次重复。将匹配'a'或'AB'。
ab?
-
*?
,+?
,??
- 的
'*'
,'+'
和'?'
预选赛都是贪婪的 ; 它们匹配尽可能多的文字越好。有时,这种行为是不希望的; 如果RE<.*>
是对匹配,它将整个字符串匹配,而不是只。<a> b <c>
<a>
添加?
了预选赛后,使得它执行在比赛非贪婪或最小的时尚; 作为几个字符可能会被匹配。使用RE<.*?>
只会匹配<a>
。 {m}
- 指定正好米以前的RE的副本应该匹配; 比赛少导致整个RE不匹配。例如,
a{6}
将匹配整整6'a'
个字符,但不是五个。 {m,n}
- 使所得稀土,从符合米到Ñ前述稀土的重复,试图匹配尽可能多的重复越好。例如,
a{3,5}
将匹配的3至5'a'
个字符。省略米指定下限为零,并省略ñ指定一个无限的上限。作为一个例子,a{4,}b
将匹配aaaab
或一千'a'
后跟一个字符b
,但不是aaab
。逗号可能不被省略或修改将与先前描述的形式相混淆。 {m,n}?
- 使所得稀土,从符合米到Ñ前述稀土的重复,试图作为匹配少重复越好。这是前面限定的非贪婪版本。例如,在6个字符的字符串
'aaaaaa'
,a{3,5}
将匹配5'a'
个字符,而a{3,5}?
将只匹配3个字符。 '\'
-
或者转义特殊字符(允许您匹配类似的字符
'*'
,'?'
等等),或者发出一个特殊序列; 特殊序列在下面讨论。如果你不使用原始字符串来表达模式,请记住,Python中也使用反斜杠作为字符串文字的转义序列; 如果转义序列不被Python的解析器识别,反斜杠和随后的字符都包含在产生的字符串中。然而,如果Python中会认识到所产生的序列,反斜线应重复两次。这是复杂的,很难理解,所以强烈建议您使用的所有原始字符串,但最简单的表达。
[]
-
用来表示一个字符集合。在这个集合中:
- 字符可以被单独罗列,例如:
[amk]
会匹配'a'
,'m'
, 或'k'
. - 字符范围可以表明通过给予两个字符和分离他们的
'-'
、 例如[z]
将匹配任何小写字母的 ASCII 字母、[0-5] [0-9]
将匹配所有两位数数字从00
到59
,和[0-9A-Fa-f]
将都匹配任何十六进制数字。If-
is escaped (e.g.[a\-z]
) or if it’s placed as the first or last character (e.g.[a-]
), it will match a literal'-'
. - 在集合内,特殊字符失去特殊意义。例如,
[(+*)]
将匹配任何字符'('
,'+'
,'* '
,或'')''
。 - 字符类如
\w
或\S
(如下定义)也接受一组内,尽管它们匹配的字符取决于是否ASCII
或LOCALE
模式是有效。 - 字符不在范围内可以通过匹配补充设定。如果该组的第一个字符是
'^'
,所有属于字符不是在设定将被匹配。例如,[^5]
将匹配除了任何字符'5'
,并且[^^]
会匹配除了任意字符'^'
。^
有,如果它不是在集合的第一个字符没有特殊含义。 - 要匹配文字
']'
集里面,前面加上反斜线,或者将其放置在集的开头。例如,双方[()[\]{}]
并[]()[{}]
都将匹配一个括号。
- 字符可以被单独罗列,例如:
'|'
-
A|B
,其中A和B可以是任意的RE,创建了一个正则表达式的匹配A或B 的RE的任意数量可以被分离'|'
以这种方式。这可以内组使用(见下文)为好。作为目标串被扫描时,RE的分隔'|'
是试图从左到右。当一个模式匹配完全,该分支被接受。这意味着一旦A
匹配时,B
将不作进一步测试,即使它会产生一个较长的总的匹配。换句话说,在'|'
操作者从来贪婪。要匹配文字'|'
,使用\|
,或将其包含在字符类中,如[|]
。 (...)
- 无论匹配正则表达式的括号内,并指示开始和一组结束; 匹配已执行之后可以检索一个组中的内容,并可以用在字符串中以后匹配
\number
特殊序列,如下所述。要匹配的文字'('
或')'
使用\(
,或\)
,或将它们括字符类中:。[(] [)]
(?...)
- 这是一个扩展符号 (a
'?'
following a'('
没有别的意义).在'?'
之后的第一个字符决定了意义和进一步的语法结构是什么.扩展通常不会创建一个新的组;(?P<name>...)
这个规则的唯一例外.以下是当前支持的扩展。 (?aiLmsux)
-
(从设置一个或多个字母
'a'
,'i'
,'L'
,'m'
,'s'
,'u'
,'x'
。)组匹配空字符串; 字母设置相应的标志:re.A
(ASCII-仅匹配),(re.I
忽略大小写),re.L
(当前位置有关),re.M
(多线),re.S
(点匹配所有),和re.X
(详细),整个正则表达式。(该标志描述模块内容。)如果你想,而不是通过一个包括标志为正则表达式的一部分,这是非常有用的标志参数的re.compile()
函数。注意,
(?x)
标志改变表达是如何解析。应当首先使用在表达式串,或之后的一个或多个空格字符。如果有前旗非空白字符,结果是不确定的。 (?:...)
- 一个正则括号的不捕获版本.Matches whatever regular expression is inside the parentheses, but the substring matched by the group cannot be retrieved after performing a match or referenced later in the pattern.
(?P<name>...)
-
和正则括号相似, 但是这个组匹配到的子字符串可以通过符号组名称name进行访问.组名称必须是有效的Python标识符, 并且每个组名称在正则表达式中只能被定义一次(注:组名必须唯一).一个符号组也是一个带编号的组, 就好像这个组没有被命名一样.(注:除了原有的编号外再指定一个额外的别名).
可以在三种上下文中引用已命名的组。如果模式是
(?P<quote>['"]).*?(?P=quote)
(例如:使用单引号或双引号来匹配一个被引用的字符串):参考上下文来组“引用” 如何引用它 以相同的模式本身 -
(?P=quote)
(如图所示) \1
处理匹配对象时 m
m.group('quote')
-
m.end('quote')
(等等。)
在传递到一个字符串 repl
的论点re.sub()
\g<quote>
\g<1>
\1
-
(?P=name)
- 反向引用一个命名组; 它匹配任何文本是由早期的命名组匹配的名称。
(?#...)
- 注释; 括号中的内容被忽略。
(?=...)
- 匹配,如果
...
匹配下,但不消耗任何字符串。这就是所谓的前向断言。例如,将匹配,如果是其次才。Isaac (?=Asimov)
'Isaac '
'Asimov'
(?!...)
- 如果比赛
...
没有一个匹配。这是一种消极的前向断言。例如,将匹配如果它只是没有后面。Isaac (?!Asimov)
'Isaac '
'Asimov'
(?<=...)
-
如果字符串中的当前位置被匹配前面匹配
...
,在当前位置结束。这被称为正面向后插入。(?<=abc)def
会找到一个匹配abcdef
,因为后向将备份3个字符,并检查所包含的模式匹配。所包含的模式必须只匹配一些固定长度的串,这意味着abc
或者a|b
是允许的,但a*
并a{3,4}
不是。请注意,这与积极向断言启动模式将不会匹配在所搜索的字符串的开始; 你很可能要使用的search()
功能,而不是match()
功能:>>> import re
>>> m = re.search('(?<=abc)def', 'abcdef')
>>> m.group(0)
'def'
这个例子查找以下连字符的一句话:
>>> m = re.search('(?<=-)\w+', 'spam-egg')
>>> m.group(0)
'egg'
-
改变在3.5版本中:增加支持固定长度的组引用。
(?<!...)
- 如果匹配字符串中的当前位置不匹配的前面
...
。这就是所谓的负向后插入。转正后向断言相似,所包含的模式必须匹配只有一些固定长度的字符串。被搜索与负向断言开始可以在字符串的开头匹配模式。 (?(id/name)yes-pattern|no-pattern)
- 将尝试配合
yes-pattern
,如果给定组ID或名称存在,并no-pattern
如果它不。no-pattern
是可选的,并且可以省略。例如,(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$)
是不良的电子邮件匹配模式,这将匹配'<user@host.com>'
以及'user@host.com'
,但不与'<user@host.com'
也不'user@host.com>'
。
特殊的序列组成的'\'
,并从以下列表中的一个字符。如果采用普通的字符不在列表上,然后将所得的稀土将匹配第二个字符。例如,\$
匹配的字符'$'
。
\number
- 匹配的组数相同的内容。组编号从1开始。例如,匹配或者,但不(注意该组之后的空间)。
(.+)\1
'the the'
'55 55'
'thethe'
这个特殊的序列可以仅用于匹配第一99组中的一个。如果第一个数字数是0,或数为3个八进制数字长,也不会被解释为一组的比赛,但与八进制值的字符数。里面'['
和']'
一个字符类,所有的数字逃逸被视为字符。 \A
- 仅在字符串的开始匹配。
\b
-
匹配空字符串,但只在一个单词的开头或结尾。一个字被定义为Unicode字母或下划线字符序列,因此单词的结尾是用空白或者非字母数字表明,非下划线Unicode字符。需要注意的是正式,
\b
被定义为一个之间的边界\w
和一\W
字符(或反之亦然)之间,或\w
与串的开头/结束。这意味着,r'\bfoo\b'
比赛'foo'
,'foo.'
,'(foo)'
,但不是或。'bar foo baz'
'foobar'
'foo3'
默认的Unicode字母数字是所使用的那些,但这可以通过使用改变
ASCII
的标志。在字符范围内,\b
表示退格符,与python的字符串兼容。 \B
- 匹配空字符串,但它只是没有在单词的开头或结尾。这意味着,
r'py\B'
比赛'python'
,'py3'
,'py2'
,但不能'py'
,'py.'
或'py!'
。\B
是正好相反\b
,因此,字字符的Unicode字母数字或下划线,虽然这可以通过使用改变ASCII
的标志。 \d
-
- 对于Unicode(STR)模式:
- 匹配任何Unicode十进制数(也就是在Unicode字符类的任何字符[钕])。这包括
[0-9]
,和许多其他的数字字符集。如果ASCII
仅用于标记[0-9]
匹配(但标志会影响整个规范表达式,从而在这种情况下使用显式[0-9]
可能是一个更好的选择)。 - 对于8位(字节)型态:
- 匹配任何十进制数字; 这相当于
[0-9]
。
\D
- 匹配这不是一个Unicode十进制数字的任何字符。这是相反的
\d
。如果该ASCII
标志用于这成为相当于[^0-9]
(但标志会影响整个规范表达式,从而在这种情况下使用显式[^0-9]
可能是一个更好的选择)。 \s
-
- 对于Unicode(STR)模式:
- 匹配的Unicode空白字符(包括,以及许多其他字符,例如,通过排版规则在许多语言要求的非中断空格)。
[ \t\n\r\f\v]
如果ASCII
使用标志,只被匹配(但使用一个明确的标志会影响整个规范表达式,从而在这样的情况下可能是一个更好的选择)。[ \t\n\r\f\v]
[ \t\n\r\f\v]
- 对于8位(字节)型态:
- 匹配考虑空白在ASCII字符集的字符; 这相当于。
[ \t\n\r\f\v]
\S
- 匹配这不是一个Unicode空白字符的任意字符。这是相反的
\s
。如果该ASCII
标志用于这成为相当于(但标志会影响整个规范表达式,从而在这种情况下使用显式可能是一个更好的选择)。[^\t\n\r\f\v]
[^ \t\n\r\f\v]
\w
-
- 对于Unicode(STR)模式:
- 匹配的Unicode字符字; 这包括可以在任何语言中的单词的一部分大多数字符,以及数字和下划线。如果
ASCII
使用标志,只[a-zA-Z0-9_]
被匹配(但使用一个明确的标志会影响整个规范表达式,从而在这样的情况下[a-zA-Z0-9_]
可能是一个更好的选择)。 - 对于8位(字节)型态:
- 考虑匹配的字母数字ASCII字符集的字符; 这相当于
[a-zA-Z0-9_]
。
\W
- 匹配这不是一个Unicode字字符的任意字符。这是相反的
\w
。如果该ASCII
标志用于这成为相当于[^a-zA-Z0-9_]
(但标志会影响整个规范表达式,从而在这种情况下使用显式[^a-zA-Z0-9_]
可能是一个更好的选择)。 \Z
- 仅在字符串的末尾匹配。
大多数被Python字符串支持的标准逃逸也由正则表达式解析器接受:
\a \b \f \n
\r \t \u \U
\v \x \\
(请注意,\b
用于表示字边界的装置,以及仅内部字符类“退格”)。
'\u'
和'\U'
转义序列只以Unicode模式的认可。在字节模式他们没有特殊处理。
八进制转义被包括在一个有限的形式。如果第一个数字是0,或者有三个八进制数字,它被认为是一个八进制转义。否则,它是一组参考。对于字符串,八进制转义始终是最多三位数字的长度。
改变在3.3版本:在'\u'
和'\U'
转义序列已被添加。
因为3.5版本已过时,将在3.6版本中移除:由未知逃逸'\'
和ASCII字母现在养不赞成警告,将在Python 3.6被禁止。
也可以看看
精通正则表达式
本书由杰弗里·弗里德尔正则表达式,由O'Reilly出版。该书的第二版不再涵盖Python的所有,但第一版涵盖了非常详细编写好的正则表达式模式。
模块内容
模块定义了几个函数、 常量和一个异常。某些函数是编译正则表达式全特性方法的简化版本。大多数复杂应用程序总是使用已编译的形式。
re.
compile
(pattern, flags=0)
将正则表达式模式编译成一个正则表达式对象,匹配时可以调用它的 match()
和 search()
方法,如下所述。
可以通过指定flags 值修改表达式的行为。值可以是任何以下变量, 组合使用 OR ( |
运算符).
The sequence
prog = re.compile(pattern)
result = prog.match(string)
等同于
result = re.match(pattern, string)
但表达式在单个程序中多次使用时, 使用re.compile()
和保存生成的正则表达式对象重用效率更高。
-
re.
search
(pattern, string, flags=0) -
通过扫描字符串寻找那里的正则表达式的第一个位置模式产生匹配,并返回相应的匹配对象。返回
None
如果字符串中没有位置的模式相匹配; 注意,这是从字符串中的某个时刻找到一个零长度的比赛不同。
-
re.
match
(pattern, string, flags=0) -
如果在开始的零个或多个字符的字符串匹配正则表达式模式,返回相应的匹配对象。返回
None
如果字符串不匹配模式; 注意,这是从零长度匹配不同。需要注意的是,即使在
MULTILINE
模式下,re.match()
将只匹配于字符串的开头,而不是在每一行的开头。If you want to locate a match anywhere in string, use
search()
instead (see also search() vs. match()).
-
re.
fullmatch
(pattern, string, flags=0) -
如果整个字符串匹配正则表达式模式,返回相应的匹配对象。返回
None
如果字符串不匹配模式; 注意,这是从零长度匹配不同。在新版本3.4。
-
re.
split
(pattern, string, maxsplit=0, flags=0) -
分割字符串用的发生模式。如果捕获括号中所用图案,然后在图案所有组的文本也被返回作为结果列表的一部分。如果maxsplit非零,至多maxsplit分裂发生,并且该串的剩余部分作为返回列表的最后一个元件。
>>> re.split('\W+', 'Words, words, words.')
['Words', 'words', 'words', '']
>>> re.split('(\W+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>> re.split('\W+', 'Words, words, words.', 1)
['Words', 'words, words.']
>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)
['0', '3', '9']
如果在分离器捕获组和它在字符串的开头相匹配,则结果将与空字符串启动。这同样适用于字符串的端:
-
>>> >>> re.split('(\W+)', '...words, words...')
['', '...', 'words', ', ', 'words', '...', '']这样,分离器组件总是在结果列表中的相同相对索引找到。
Note
注意
split()
目前并不在一个空的模式匹配拆分的字符串。例如:>>> >>> re.split('x*', 'axbc')
['a', 'bc']在3.1版本的变化:增加了可选的标志参数。
改变在3.5版本中:分割上可以匹配一个空字符串现在提出一个警告的模式。现在的模式,只能匹配空字符串被拒绝。
>>> >>> re.split("^$", "foo\n\nbar\n", flags=re.M)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
...
ValueError: split() requires a non-empty pattern match.在3.1版本的变化:增加了可选的标志参数。
改变在3.5版本中:分割上可以匹配一个空字符串现在提出一个警告的模式。现在的模式,只能匹配空字符串被拒绝。
-
re.
findall
(pattern, string, flags=0) -
Return all non-overlapping matches of pattern in string, as a list of strings. The string是从左到右扫描的,所以匹配的内容是按照该顺序来的If one or more groups are present in the pattern, return a list of groups; this will be a list of tuples if the pattern has more than one group. Return all non-overlapping matches of pattern in string, as a list of strings. The string是从左到右扫描的,所以匹配的内容是按照该顺序来的If one or more groups are present in the pattern, return a list of groups; this will be a list of tuples if the pattern has more than one group. Empty matches are included in the result unless they touch the beginning of another match.
-
re.
finditer
(pattern, string, flags=0) -
返回一个迭代器产生的匹配对象,在为RE的所有非重叠的匹配模式的字符串。该字符串进行扫描左到右,而匹配的中发现的顺序返回。空场比赛都包括在结果,除非他们碰另一场比赛的开始。
-
re.
sub
(pattern, repl, string, count=0, flags=0) -
返回由替换最左边的非重叠事件中获得的字符串模式在字符串的置换REPL。如果未找到模式,串原样返回。REPL可以是一个字符串或函数; 如果它是一个字符串,任何反斜杠在它被处理。即,
\n
被转换为单一的换行符,\r
被转换成一个回车,等等。未知的转义如\&
被单独留在家中。反向引用,如\6
,被替换为由组6中的图案相匹配的子串。例如:>>> >>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',
... r'static PyObject*\npy_\1(void)\n{',
... 'def myfunc():')
'static PyObject*\npy_myfunc(void)\n{'如果REPL是一个函数,它被称为为每个非重叠出现的格局。该函数有一个匹配的对象参数,返回替换字符串。例如:
>>> >>> def dashrepl(matchobj):
... if matchobj.group(0) == '-': return ' '
... else: return '-'
>>> re.sub('-{1,2}', dashrepl, 'pro----gram-files')
'pro--gram files'
>>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)
'Baked Beans & Spam'该图案可以是字符串或RE对象。
可选参数计数是要被替换的模式出现的最大数量; 计数必须是一个非负整数。如果省略或为零,所有出现将被替换。该模式匹配空更换,只有当不相邻的上一个比赛,所以回报。
sub('x*', '-','abc')
'-a-b-c-'
在字符串类型的REPL参数,除了上述的字符转义和反向引用,
\g<name>
将使用指定的组相匹配的子字符串name
,由定义的(?P<name>...)
语法。\g<number>
使用相应的组号;\g<2>
因此等效于\2
,但不是在更换诸如模棱两可\g<2>0
。\20
将被解释为对组20中的引用,而不是对第2组的基准后跟文字字符'0'
。反向引用\g<0>
整个字符串替代由RE相匹配。在3.1版本的变化:增加了可选的标志参数。
在3.5版本中改为:无与伦比的群体被替换为空字符串。
因为3.5版本已过时,将在3.6版本中删除:未知逃逸包括
'\'
与ASCII字母现在养不赞成警告,将在Python 3.6被禁止。
-
re.
subn
(pattern, repl, string, count=0, flags=0) -
执行相同的操作
sub()
,但返回的元组。(new_string, number_of_subs_made)
在3.1版本的变化:增加了可选的标志参数。
在3.5版本中改为:无与伦比的群体被替换为空字符串。
-
re.
escape
(string) -
逃避所有的模式,除了ASCII字母,数字和字符
'_'
。如果你想匹配,可能有正则表达式元字符在它的任意文字字符串,这非常有用。在3.3版本中更改:该
'_'
字符不再逃跑。
-
re.
purge
() -
清除正则表达式缓存。
-
exception
re.
error
(msg, pattern=None, pos=None) -
这里的时候,一个字符串传递的功能之一提出的例外是不是一个有效的正则表达式(例如,它可能包含括号不匹配),或在编译或匹配时发生其他一些错误。如果一个字符串包含敌不过一个模式,是永远不会出错。错误实例具有以下附加属性:
msg
-
未格式化的错误消息。
pattern
-
正则表达式模式。
pos
-
指数模式,其中编译失败。
lineno
-
相对于线路POS。
colno
-
相应于列POS。
在3.5版本中变化:增加了额外的属性。
6.2.3. 正则表达式对象
已编译的正则表达式对象支持下列方法和属性︰
-
regex.
search
(string[, pos[, endpos]]) -
扫描string 寻找正则表达式产生匹配后的第一个位置 , 然后返回一个相对应的 match object.Return
None
if no position in the string matches the pattern; note that this is different from finding a zero-length match at some point in the string.可选的第二个参数 pos 给索引在字符串中搜索在哪里开始;它默认为
0
。This is not completely equivalent to slicing the string; the'^'
pattern character matches at the real beginning of the string and at positions just after a newline, but not necessarily at the index where the search is to start.可选参数endpos限制字符串将在多大程度上被搜索; 将它作为字符串是否endpos字符长,所以只能从人物POS机,以将搜索匹配。
endpos - 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
<_sre.SRE_Match object; span=(0, 1), match='d'>
>>> pattern.search("dog", 1) # No match; search doesn't include the "d"
-
regex.
match
(string[, pos[, endpos]]) -
I
如果在零个或多个字符开头的字符串匹配这个正则表达式,返回相应的匹配对象。如果返回
None
,则该字符串不匹配模式;注意这不同于一个零字节长度的匹配。可选的POS和endpos参数的含义与对于相同的
search()
方法。>>> >>> pattern = re.compile("o")
>>> pattern.match("dog") # 没有匹配的“O”是不是在“狗”的开始。
>>> pattern.match("dog", 1) # 匹配为“O”是“狗”的第2个字符。
<_sre.SRE_Match object; span=(1, 2), match='o'>如果您想要的任何地方找到一个匹配的字符串,用
search()
代替, usesearch()
instead (see also search() vs. match()).
-
regex.
fullmatch
(string[, pos[, endpos]]) -
如果整个字符串这个正则表达式匹配,返回相应的匹配对象。返回
None
如果字符串不匹配模式; 注意,这是从零长度匹配不同。可选的POS和endpos参数的含义与对于相同的
search()
方法。>>> >>> 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.
<_sre.SRE_Match object; span=(1, 3), match='og'>New in version 3.4.
-
regex.
split
(string, maxsplit=0) -
相同的
split()
功能,采用编图案。
-
regex.
findall
(string[, pos[, endpos]]) -
类似于
findall()
的功能,使用已编译的模版,但也接受可选的 pos 和 endpos 参数限制搜索区域像match ()
。
-
regex.
finditer
(string[, pos[, endpos]]) -
类似于
findall()
的功能,使用已编译的模版,但也接受可选的 pos 和 endpos 参数像match ()
限制搜索区域。
-
regex.
sub
(repl, string, count=0) -
相同的
sub()
功能,采用编图案。
-
regex.
subn
(repl, string, count=0) -
相同的
subn()
功能,采用编图案。
-
regex.
flags
-
T正则表达式匹配标志。这是提供给标志的组合
compile()
,任何(?...)
在图案内联的标志,并且如隐标志UNICODE
如果该图案是Unicode字符串。
-
regex.
groups
-
在图案捕获基团的数目。
-
regex.
groupindex
-
对应的字典定义为任何符号的组名
(?P<id>)
,以组号码。如果没有符号组分别在模式中使用的字典是空的。
-
regex.
pattern
-
该模式字符串从中RE对象被编译。
Match 对象
Match对象总是有一个布尔值True
。由于match()
与search()
返回None
时没有匹配,您可以测试是否有一个简单的比赛if
语句:
match = re.search(pattern, string)
if match:
process(match)
Match 对象支持下列方法和属性︰
-
match.
expand
(模板) -
返回由该模板串做反斜杠替换获得的字符串模板,由做
sub()
方法。逃逸如\n
被转换成相应的字符,数字反向引用(\1
,\2
)并命名为反向引用(\g<1>
,\g<name>
)是由相应的组的内容替换。在3.5版本中改为:无与伦比的群体被替换为空字符串。
正则表达式实例
Checking for a Pair
在这个例子中,我们将使用下面的辅助函数来显示匹配的对象多了几分优雅:
def displaymatch(match):
if match is None:
return None
return '<Match: %r, groups=%r>' % (match.group(), match.groups())
假设你正在编写一个球员的手表示为5个字符的字符串代表一个卡的每个字符扑克节目,“一”的王牌,“K”为王,“Q”为皇后,“J”的插孔, “T”为10,“2”至“9”表示与该值的卡。
要查看是否给定的字符串是一个有效的手,我们可以做到以下几点:
>>> >>> valid = re.compile(r"^[a2-9tjqk]{5}$")
>>> displaymatch(valid.match("akt5q")) # Valid.
"<Match: 'akt5q', groups=()>"
>>> displaymatch(valid.match("akt5e")) # Invalid.
>>> displaymatch(valid.match("akt")) # Invalid.
>>> displaymatch(valid.match("727ak")) # Valid.
"<Match: '727ak', groups=()>"
这最后一手,"727ak"
载一对,两个同样看重卡。要使用正则表达式匹配这一点,我们可以使用反向引用这样:
>>> >>> pair = re.compile(r".*(.).*\1")
>>> displaymatch(pair.match("717ak")) # Pair of 7s.
"<Match: '717', groups=('7',)>"
>>> displaymatch(pair.match("718ak")) # No pairs.
>>> displaymatch(pair.match("354aa")) # Pair of aces.
"<Match: '354aa', groups=('a',)>"
要找出对包括什么牌,我们可以用group()
以下方式匹配对象的方法:
>>> >>> pair.match("717ak").group(1)
'7' # Error because re.match() returns None, which doesn't have a group() method:
>>> pair.match("718ak").group(1)
Traceback (most recent call last):
File "<pyshell#23>", line 1, in <module>
re.match(r".*(.).*\1", "718ak").group(1)
AttributeError: 'NoneType' object has no attribute 'group' >>> pair.match("354aa").group(1)
'a'
6.2.5.2. Simulating scanf()
Python中目前没有一个相当于scanf()
。正则表达式一般都比较强大,虽也更详细,比scanf()
格式字符串。下表提供的一些或多或少等价映射scanf()
格式标记和正则表达式。
scanf() Token |
Regular Expression |
---|---|
%c |
. |
%5c |
.{5} |
%d |
[-+]?\d+ |
%e , %E , %f , %g
|
[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)? |
%i |
[-+]?(0[xX][\dA-Fa-f]+|0[0-7]*|\d+) |
%o |
[-+]?[0-7]+ |
%s |
\S+ |
%u |
\d+ |
%x , %X
|
[-+]?(0[xX])?[\dA-Fa-f]+ |
提取像一个字符串的文件名和号码
/usr/sbin/sendmail - 0 errors, 4 warnings
你可以使用一个scanf()
类似的格式
%s - %d errors, %d warnings
等效正则表达式会
(\S+) - (\d+) errors, (\d+) warnings
search() vs. match()
Python 提供基于正则表达式两个不同的原语操作re.match()
仅在字符串的开头进行匹配检查,而re.search()
进行匹配的字符串中的任何检查(这是Perl并默认情况下)。
例如:
>>> >>> re.match("c", "abcdef") # No match
>>> re.search("c", "abcdef") # Match
<_sre.SRE_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
<_sre.SRE_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
<_sre.SRE_Match object; span=(4, 5), match='X'>
Making a Phonebook通讯录
split()
将一个字符串复制到传递模式分隔列表。该方法是非常宝贵的,用于将文本数据转换为可以容易地读取和Python的改性如下面的示例,创建一个电话簿证明的数据结构。
首先,这里是输入。通常,它可能来自一个文件,这里我们使用三引号字符串语法:
>>> >>> text = """Ross McFluff: 834.345.1254 155 Elm Street
...
... Ronald Heathmore: 892.345.3428 436 Finley Avenue
... Frank Burger: 925.541.7625 662 South Dogwood Way
...
...
... Heather Albrecht: 548.326.4584 919 Park Place"""
的条目被一个或多个新行分开。现在我们转换成字符串具有其自身的条目中的每个非空行的列表:
>>> >>> entries = re.split("\n+", text)
>>> entries
['Ross McFluff: 834.345.1254 155 Elm Street',
'Ronald Heathmore: 892.345.3428 436 Finley Avenue',
'Frank Burger: 925.541.7625 662 South Dogwood Way',
'Heather Albrecht: 548.326.4584 919 Park Place']
最后,拆每个条目与姓,名,电话号码和地址的列表。我们使用maxsplit
的参数,split()
因为地址有空格,我们的分裂模式,在其中:
>>> >>> [re.split(":? ", entry, 3) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155 Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919 Park Place']]
The :?
pattern matches the colon after the last name, so that it does not occur in the result list. With a maxsplit
of 4
, 我们可以分开街道名称门牌号码:
>>> >>> [re.split(":? ", entry, 4) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]
Text Munging文字改写
sub()
替换字符串或函数的结果的图形的每一个发生。这个例子演示了使用sub()
带有功能为“munge”的文字,或在随机除了第一个和最后一个字符一个句子中每个单词的所有字符的顺序:
>>> >>> def repl(m):
... inner_word = list(m.group(2))
... random.shuffle(inner_word)
... return m.group(1) + "".join(inner_word) + m.group(3)
>>> text = "Professor Abdolmalek, please report your absences promptly."
>>> re.sub(r"(\w)(\w+)(\w)", repl, text)
'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.'
>>> re.sub(r"(\w)(\w+)(\w)", repl, text)
'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'
找到所有副词
findall()
匹配所有的模式的出现,不仅是第一个search()
做。例如,如果一个人是一个作家,想找到所有的副词的一些文字,他或她可能使用findall()
的方式如下:
>>> >>> text = "He was carefully disguised but captured quickly by police."
>>> re.findall(r"\w+ly", text)
['carefully', 'quickly']
找到所有的副词及其位置
如果想了解比匹配的文本模式的所有匹配的更多信息,finditer()
因为它提供了非常有用的匹配对象,而不是字符串。与继续前面的例子,如果一个是谁想要找到所有的副词的作家和他们的立场的一些文字,他或她会用finditer()
的方式如下:
>>> >>> text = "He was carefully disguised but captured quickly by police."
>>> for m in re.finditer(r"\w+ly", text):
... print('%02d-%02d: %s' % (m.start(), m.end(), m.group(0)))
07-16: carefully
40-47: quickly
raw字符串表示
原始字符串符号(r"text"
)保持正则表达式理智。没有它,每一个反斜杠('\'
)在正则表达式必须与另一个逃跑呢前缀。例如,以下两个行代码在功能上是相同的:
>>> >>> re.match(r"\W(.)\1\W", " ff ")
<_sre.SRE_Match object; span=(0, 4), match=' ff '>
>>> re.match("\\W(.)\\1\\W", " ff ")
<_sre.SRE_Match object; span=(0, 4), match=' ff '>
当一个人想匹配一个反斜杠,它必须在正则表达式进行转义。随着原始字符串符号,这意味着r"\\"
。如果没有原始字符串符号,你必须使用"\\\\"
,使得代码功能相同下面几行:
>>> >>> re.match(r"\\", r"\\")
<_sre.SRE_Match object; span=(0, 1), match='\\'>
>>> re.match("\\\\", r"\\")
<_sre.SRE_Match object; span=(0, 1), match='\\'>
编写一个标记
一个标记生成器或扫描仪分析字符串进行分类字符组。这是写一个编译器或解释有益的第一步。
文本类别与正则表达式指定。该技术是将这些组合成一个单一的主正则表达式和遍历连续匹配:
import collections
import re Token = collections.namedtuple('Token', ['typ', 'value', 'line', 'column']) def tokenize(code):
keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'}
token_specification = [
('NUMBER', r'\d+(\.\d*)?'), # Integer or decimal number
('ASSIGN', r':='), # Assignment operator
('END', r';'), # Statement terminator
('ID', r'[A-Za-z]+'), # Identifiers
('OP', r'[+\-*/]'), # Arithmetic operators
('NEWLINE', r'\n'), # Line endings
('SKIP', r'[ \t]+'), # Skip over spaces and tabs
('MISMATCH',r'.'), # Any other character
]
tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)
line_num = 1
line_start = 0
for mo in re.finditer(tok_regex, code):
kind = mo.lastgroup
value = mo.group(kind)
if kind == 'NEWLINE':
line_start = mo.end()
line_num += 1
elif kind == 'SKIP':
pass
elif kind == 'MISMATCH':
raise RuntimeError('%r unexpected on line %d' % (value, line_num))
else:
if kind == 'ID' and value in keywords:
kind = value
column = mo.start() - line_start
yield Token(kind, value, line_num, column) statements = '''
IF quantity THEN
total := total + price * quantity;
tax := price * 0.05;
ENDIF;
''' for token in tokenize(statements):
print(token)
标记生成器产生以下的输出:
Token(typ='IF', value='IF', line=2, column=4)
Token(typ='ID', value='quantity', line=2, column=7)
Token(typ='THEN', value='THEN', line=2, column=16)
Token(typ='ID', value='total', line=3, column=8)
Token(typ='ASSIGN', value=':=', line=3, column=14)
Token(typ='ID', value='total', line=3, column=17)
Token(typ='OP', value='+', line=3, column=23)
Token(typ='ID', value='price', line=3, column=25)
Token(typ='OP', value='*', line=3, column=31)
Token(typ='ID', value='quantity', line=3, column=33)
Token(typ='END', value=';', line=3, column=41)
Token(typ='ID', value='tax', line=4, column=8)
Token(typ='ASSIGN', value=':=', line=4, column=12)
Token(typ='ID', value='price', line=4, column=15)
Token(typ='OP', value='*', line=4, column=21)
Token(typ='NUMBER', value='0.05', line=4, column=23)
Token(typ='END', value=';', line=4, column=27)
Token(typ='ENDIF', value='ENDIF', line=5, column=4)
Token(typ='END', value=';', line=5, column=9)
re常用正则表达式符号
'.' 默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
'^' 匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
'$' 匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以
'*' 匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac") 结果为['abb', 'ab', 'a']
'+' 匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
'?' 匹配前一个字符1次或0次
'{m}' 匹配前一个字符m次
'{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
'|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
'(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c '\A' 只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的
'\Z' 匹配字符结尾,同$
'\d' 匹配数字0-9
'\D' 匹配非数字
'\w' 匹配[A-Za-z0-9]
'\W' 匹配非[A-Za-z0-9]
's' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t' '(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '1993'}
最常用的匹配语法
re.match 从头开始匹配
re.search 匹配包含
re.findall 把所有匹配到的字符放到以列表中的元素返回
re.splitall 以匹配到的字符当做列表分隔符
re.sub 匹配字符并替换
match
# match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None match(pattern, string, flags=0)
# pattern: 正则模型
# string : 要匹配的字符串
# falgs : 匹配模式
X VERBOSE Ignore whitespace and comments for nicer looking RE's.
I IGNORECASE Perform case-insensitive matching.
M MULTILINE "^" matches the beginning of lines (after a newline)
as well as the string.
"$" matches the end of lines (before a newline) as well
as the end of the string.
S DOTALL "." matches any character at all, including the newline. A ASCII For string patterns, make \w, \W, \b, \B, \d, \D
match the corresponding ASCII character categories
(rather than the whole Unicode categories, which is the
default).
For bytes patterns, this flag is the only available
behaviour and needn't be specified. L LOCALE Make \w, \W, \b, \B, dependent on the current locale.
U UNICODE For compatibility only. Ignored for string patterns (it
is the default), and forbidden for bytes patterns.
实例:
# 无分组
r = re.match("h\w+", origin)
print(r.group()) # 获取匹配到的所有结果
print(r.groups()) # 获取模型中匹配到的分组结果
print(r.groupdict()) # 获取模型中匹配到的分组结果 # 有分组 # 为何要有分组?提取匹配成功的指定内容(先匹配成功全部正则,再匹配成功的局部内容提取出来) r = re.match("h(\w+).*(?P<name>\d)$", origin)
print(r.group()) # 获取匹配到的所有结果
print(r.groups()) # 获取模型中匹配到的分组结果
print(r.groupdict()) # 获取模型中匹配到的分组中所有执行了key的组 Demo
search
# search,浏览整个字符串去匹配第一个,未匹配成功返回None
# search(pattern, string, flags=0)
实例:
# 无分组 r = re.search("a\w+", origin)
print(r.group()) # 获取匹配到的所有结果
print(r.groups()) # 获取模型中匹配到的分组结果
print(r.groupdict()) # 获取模型中匹配到的分组结果 # 有分组 r = re.search("a(\w+).*(?P<name>\d)$", origin)
print(r.group()) # 获取匹配到的所有结果
print(r.groups()) # 获取模型中匹配到的分组结果
print(r.groupdict()) # 获取模型中匹配到的分组中所有执行了key的组 demo
import re obj = re.match('\d+', '123uuasf')
if obj:
print(obj.group())
a = '123abc456'
print(re.search('([0-9]*)([a-z]*)([0-9]*)',a).group())#123abc456
print(re.search('([0-9]*)([a-z]*)([0-9]*)',a).group(0))#123abc456
print(re.search('([0-9]*)([a-z]*)([0-9]*)',a).group(1))#123
print(re.search('([0-9]*)([a-z]*)([0-9]*)',a).group(2))#abc
import re obj = re.search('\d+', 'u123uu888asf')
if obj:
print(obj.group())
group和groups
a = "123abc456"
print re.search("([0-9]*)([a-z]*)([0-9]*)", a).group() print re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(0)
print re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(1)
print re.search("([0-9]*)([a-z]*)([0-9]*)", a).group(2) print re.search("([0-9]*)([a-z]*)([0-9]*)", a).groups()
findall
# findall,获取非重复的匹配列表;如果有一个组则以列表形式返回,且每一个匹配均是字符串;如果模型中有多个组,则以列表形式返回,且每一个匹配均是元祖;
# 空的匹配也会包含在结果中
#findall(pattern, string, flags=0)
实例:
# 无分组
r = re.findall("a\w+",origin)
print(r) # 有分组
origin = "hello alex bcd abcd lge acd 19"
r = re.findall("a((\w*)c)(d)", origin)
print(r) Demo import re obj = re.findall('\d+', 'fa123uu888asf')
print(obj)
sub
# sub,替换匹配成功的指定位置字符串 sub(pattern, repl, string, count=0, flags=0)
# pattern: 正则模型
# repl : 要替换的字符串或可执行对象
# string : 要匹配的字符串
# count : 指定匹配个数
# flags : 匹配模式
实例:
# 与分组无关 origin = "hello alex bcd alex lge alex acd 19"
r = re.sub("a\w+", "999", origin, 2)
print(r)
根据指定匹配进行分组
content = "'1 - 2 * ((60-30+1*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2) )'"
new_content = re.split('\*', content)
# new_content = re.split('\*', content, 1)
print new_content
2
content = "'1 - 2 * ((60-30+1*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2) )'"
new_content = re.split('[\+\-\*\/]+', content)
# new_content = re.split('\*', content, 1)
print new_content
3
inpp = '1-2*((60-30 +(-40-5)*(9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2))'
inpp = re.sub('\s*','',inpp)
new_content = re.split('\(([\+\-\*\/]?\d+[\+\-\*\/]?\d+){1}\)', inpp, 1)
print new_content
相比于str.split更加强大
实例:计算器源码
split
# split,根据正则匹配分割字符串 split(pattern, string, maxsplit=0, flags=0)
# pattern: 正则模型
# string : 要匹配的字符串
# maxsplit:指定分割个数
# flags : 匹配模式
实例:
# 无分组
origin = "hello alex bcd alex lge alex acd 19"
r = re.split("alex", origin, 1)
print(r) # 有分组 origin = "hello alex bcd alex lge alex acd 19"
r1 = re.split("(alex)", origin, 1)
print(r1)
r2 = re.split("(al(ex))", origin, 1)
print(r2) Demo
IP:
^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$
手机号:
^1[3|4|5|8][0-9]\d{8}$
邮箱:
[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+ 常用正则表达式
字符串模板匹配
re
模块为高级字符串处理提供了正则表达式工具。对于复杂的匹配和操作,正则表达式提供了简洁、优化的解决方案:
>>> import re
>>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
['foot', 'fell', 'fastest']
>>> re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat')
'cat in the hat'
当只需要简单的功能时,最好使用字符串方法,因为它们更容易阅读和调试:
>>> 'tea for too'.replace('too', 'two')
'tea for two'
数学
math
模块提供基于c库函数的浮点运算.
>>> import math
>>> math.cos(math.pi / 4)
0.70710678118654757
>>> math.log(1024, 2)
10.0
random
的模块提供了进行随机选择的工具︰
>>> import random
>>> random.choice(['apple', 'pear', 'banana'])
'apple'
>>> random.sample(range(100), 10) # sampling without replacement
[30, 83, 16, 4, 8, 81, 41, 50, 18, 33]
>>> random.random() # random float
0.17970987693706186
>>> random.randrange(6) # random integer chosen from range(6)
4
statistics
模块计算数值数据的基本统计特性 (均值、 中位数、 方差,等)。e :
>>> import statistics
>>> data = [2.75, 1.75, 1.25, 0.25, 0.5, 1.25, 3.5]
>>> statistics.mean(data)
1.6071428571428572
>>> statistics.median(data)
1.25
>>> statistics.variance(data)
1.3720238095238095