本模块提供了类似于Perl的正则表达式匹配操作。要匹配的模式和字符串可以是Unicode字符串以及8位字符串。
正则表达式使用反斜杠字符('\')来表示特殊的形式或者来使特殊的字符消除效果,成为普通字符。这与字符串字面值中相同目的的相同字符的用法冲突;例如,要匹配一个反斜线字面值,你必须写成'\\\\'作为模式字符串,因为正则表达式必须是\\,每个反斜线在Python字符串字面值内部必须表达成\\。
解决方案是将Python的原始字符串表示法用于正则表达式模式; 在以'r'为前缀的字符串字面值中,反斜杠不会以任何特殊的方式处理。所以r"\n"是一个包含'\'和'n'两个字符的字符串,而"\n"是包含一个换行符的单字符字符串。通常在Python代码中,模式的表示使用这种原始字符串符号。
重要的注意事项是大部分正则表达式操作可以利用模块级别的函数和RegexObject的方法。这些函数是快捷的方式,它们不要求你首先编译一个正则表达式对象,但会遗漏一些微优的参数。
请参见
正则表达式(简称RE)确定一组匹配它字符串;此模块中的函数让你检查一个特定的字符串是否匹配给定的正则表达式(或给定的正则表达式是否匹配特定的字符串,这可归结为同一件事)。
正则表达式可以连接以形成新的正则表达式;如果A和B两个都是正则表达式,那么AB也是正则表达式。一般来说,如果字符串p匹配A且另一个字符串q匹配B,那么字符串pq将匹配AB。除非A或B包含低优先级的操作;A和B之间存在边界条件;或有编号的组的引用。因此,复杂的表达式可以轻松地从这里所描述的更简单的原始表达式构建。关于理论的细节及正则表达式的实现,请参阅上文引用的Friedl的书或任何一本有关编译器构造的教科书。
下面简要说明了正则表达式的格式。进一步的信息和更友好的演示,请参阅正则表达式HOWTO。
正则表达式可以包含特殊和普通字符。最普通的字符,如'A'、'a'、或'0'是最简单的正则表达式;它们简单地匹配它们自己。你可以连接普通字符,所以last匹配字符串'last'。(在本节剩下的部分,我们将把正则表达式写成不带引号的形式这种独特风格,要匹配的字符串写成带引号的形式'用单引号'。)
某些字符,比如'|'或'(',比较特殊。特殊字符要么表示某个类别的普通字符,要么影响它们周围的正则表达式如何解释。正则表达式的模式字符串不可以包含空字节,但可以使用\number符号指定空字节,例如'\x00'。
特殊字符有:
对任一特殊字符进行转义(允许您匹配字符(如'*',' ? ',等等),或只是一个特殊的序列;特殊序列在下面讨论。
如果你不使用原始字符串来表达模式,记住在字符串字面值中Python也使用反斜杠作为转义序列;如果转义序列不能被Python解析器识别,那么结果字符串中包含反斜杠和后面的字符。但是,如果Python会识别所产生的序列,反斜杠应该重复两次。这比较复杂和难以理解,因此强烈建议你为所有即使是最简单的表达式使用原始字符串。
用来表示一个字符集合。在一个集合中:
(集合'i', 'L', 'm', 's', 'u', 'x'中的一个或多个字母。)这个分组匹配空字符串;这些字母给整个正则表达式设置相应的标记:re.I
(忽略大小写),re.L
(依赖区域设置),re.M
(多行),re.S
(点号匹配所有字符),re.U
(依赖Unicode),re.X
(详细模式)。(这些标记在模块的内容中讲述)。如果您希望将这些标志作为正则表达式的一部分,而不是将flag参数传递给re.compile()函数,这将非常有用。
请注意,(?x)标记将更改解析表达的方式。它应使用在表达式字符串的开始,或一个或多个空白字符之后。如果在这个标记之前有非空白字符,结果是未定义的。
通过符号组名称name可以访问类似于常规的括号,但由组匹配的子字符串。组名必须是有效的 Python 标识符,并且每个组名必须在正则表达式内只有一次定义。海员象征性的组织也是带编号的组,就好像组未被命名。
Named groups can be referenced in three contexts. If the pattern is (?P<quote>['"]).*?(?P=quote) (i.e. matching a string quoted with either single or double quotes):
Context of reference to group “quote” | Ways to reference it |
---|---|
in the same pattern itself |
|
when processing match object m |
|
in a string passed to the repl argument of re.sub() |
|
匹配字符串中当前位置的前面是在当前位置结束的...的匹配。这就被所谓的积极回顾后发断言。 (? < = 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'
Will try to match with yes-pattern if the group with given id or name exists, and with no-pattern if it doesn’t. no-pattern is optional and can be omitted. For example, (<)?(w+@w+(?:.w+)+)(?(1)>) is a poor email matching pattern, which will match with '<user@host.com>' as well as 'user@host.com', but not with '<user@host.com'.
在 2.4 版本新。
如果区域设置和UNICODE标志包括为一个特定的序列,区域设置标志可将第一次跟着UNICODE的生效。
由正则表达式分析器也接受大多数支持通过 Python 字符串的标准转义:
\a \b \f \n
\r \t \v \x
\\
(请注意,用来表示单词边界,并意味着"退格键"只能在字符类的内部。)
八进制转义中有限的形式包括: 如果第一个数字为 0,或者如果有三个八进制数字,它被认为是八进制转义符。否则,它是组引用。字符串文本总是八进制转义顶多是三个数字的长度。
模块定义了几个函数、 常量和异常。某些功能是充分的特色方法的已编译的正则表达式的简化的版本。大多数非平凡应用程序总是使用的已编译的形式。
将正则表达式模式编译成一个正则表达式对象,它可以用于匹配使用它的match ()和search ()方法,如下所述。
可以通过指定flags值修改表达式的行为。值可以是任何以下变量,使用组合 OR ( |运算符)。
序列
prog = re.compile(pattern)
result = prog.match(string)
等效于
result = re.match(pattern, string)
但使用re.compile()和保存所产生的正则表达式对象重用效率更高时该表达式会在单个程序中多次使用。
注
传递给re.match()、 re.search()或re.compile()的最新模式的已编译的版本进行缓存,所以只有几个正则表达式的程序使用一次不必担心编译正则表达式。
显示调试信息编译的表达式。
当指定时,模式字符' ^'匹配字符串的开头以及每个行的开头(紧接每个换行符); 模式字符'$'匹配字符串的末尾以及每一行的结尾(紧靠每个换行符之前)。默认情况下, '^'只匹配字符串的开始,'$'只匹配字符串的末尾和字符串末尾换行符(如果有的话)之前的位置。
此标志允许您编写正则表达式,看起来更好。在模式中的空白将被忽略,除非当在字符类或者前面非转义反斜杠,和,当一条线包含一个'#'既不在字符类中或由非转义反斜杠,从最左侧的所有字符之前,这种'#'通过行末尾将被忽略。
这意味着两个以下正则表达式匹配的对象,一个十进制数是相同的功能:
a = re.compile(r"""\d + # the integral part
\. # the decimal point
\d * # some fractional digits""", re.X)
b = re.compile(r"\d+\.\d*")
扫描字符串,寻找的第一个由该正则表达式模式产生匹配的位置,并返回相应的MatchObject实例。返回None如果没有字符串中的位置匹配模式 ;请注意这不同于在字符串的某个位置中找到一个长度为零的匹配。
如果在字符串的开头的零个或更多字符匹配正则表达式模式,将返回相应的MatchObject实例。返回None则该字符串中与模式不匹配;请注意这是不同于零长度匹配。
请注意,即使在多行模式下, re.match()将只匹配字符串的开头,而不是在每个行的开头。
如果你想要在字符串中的任意位置定位一个匹配,改用search () (请参见search () 与 match ())。
将字符串拆分的模式的匹配项。如果在模式中使用捕获括号,则然后也作为结果列表的一部分返回的文本模式中的所有组。如果maxsplit不为零,顶多maxsplit分裂发生,并且该字符串的其余部分将作为列表的最后一个元素返回。(不兼容性说明: 在原始的 Python 1.5 版本中, 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', '...', '']
这样一来,分离器组件始终都位于相同的相对索引在结果列表中 (例如,如果有是在分离器,在 0,第二个捕获组等等)。
请注意,拆分将永远不会拆分对空模式匹配的字符串。举个例子:
>>> re.split('x*', 'foo')
['foo']
>>> re.split("(?m)^$", "foo\n\nbar\n")
['foo\n\nbar\n']
2.7 版本中的更改:添加可选的标志参数。
在string中,返回所有非重叠匹配的pattern组成的一个字符串列表。该字符串是从左到右扫描的,匹配按照发现的顺序返回。如果一个或多个组是本模式中,返回一个列表的群体 ;如果该模式具有多个组,这将是元组的列表。空匹配包含在结果中,除非他们接触到另一场匹配的开头。
在 1.5.2 版本新。
2.4 版本中的更改:添加可选的标志参数。
返回一个迭代器符合MatchObject情况 在 RE模式字符串中的所有非重叠的匹配。该字符串是扫描的左到右,和按发现的顺序返回匹配。空匹配包含在结果中,除非他们接触的另一个匹配的开头。
新版本 2.2 中的。
2.4 版本中的更改:添加可选的标志参数。
通过替换repl将string中最左侧的非重叠事件替换为pattern返回所获得的字符串。如果pattern没有被找到, string不变。repl 可以是一个字符串或一个函数;如果是一个字符串, 任何反斜杠转义都会实现。那就是,\n会转化成一个换行符,\r 会转化成一个回车,等等。 未知的转义字符例如 \j不做处理。Backreferences, such as \6, are replaced with the substring matched by group 6 in the pattern. For example:
>>> 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'
模式可以是一个字符串或重新对象。
可选参数count是替换出现的模式的最大次数;count必须为非负整数。如果省略或为零,所有出现都将被替换。空匹配模式只有当不毗邻前一个匹配才替换,所以sub('x*', '-', 'abc')返回'-a-b-c-'。
In string-type repl arguments, in addition to the character escapes and backreferences described above, \g<name> will use the substring matched by the group named name, as defined by the (?P<name>...) syntax. \g<number> uses the corresponding group number; \g<2> is therefore equivalent to \2, but isn’t ambiguous in a replacement such as \g<2>0. \20 would be interpreted as a reference to group 20, not a reference to group 2 followed by the literal character '0'. The backreference \g<0> substitutes in the entire substring matched by the RE.
2.7 版本中的更改:添加可选的标志参数。
执行相同的操作,如sub(),但返回一个元组(new_string, number_of_subs_made)。
2.7 版本中的更改:添加可选的标志参数。
返回的字符串与所有非字母数字带有反斜杠 ;这是有用的如果你想匹配一个任意的文本字符串,在它可能包含正则表达式元字符。
清除正则表达式缓存。
当一个字符串传递给这里的函数之一时引发的异常不是有效的正则表达式 (例如,它可能包含不匹配的括号) 或其他一些错误在编译或匹配过程中发生的时。如果一个字符串包含不匹配的一种模式,它永远不会是一个错误。
RegexObject 类支持下列方法和属性:
扫描字符串寻找一个位置,在此正则表达式产生的匹配,并返回相应的作法实例。返回无如果没有字符串中的位置匹配模式 ;请注意这是不同于找到一个长度为零的匹配在一些点在字符串中。
可选的第二个参数pos给索引在字符串中搜索在哪里开始 ;它将默认为0。这并不完全等于切片的字符串 ; ' ^'模式字符匹配在真正开始的字符串和位置刚换行,但不是一定是在开始搜索的索引。
可选参数endpos限制了多远的字符串将被搜索 ;它将,如果字符串是endpos个字符长,因此,只有从pos到字符endpos - 1将搜索匹配项。如果endpos小于pos,没有比赛会发现,否则,如果rx是已编译的正则表达式对象, rx.search (字符串, 0, 50)相当于rx.search (字符串 [: 50], 0)。
>>> pattern = re.compile("d")
>>> pattern.search("dog") # Match at index 0
<_sre.SRE_Match object at ...>
>>> pattern.search("dog", 1) # No match; search doesn't include the "d"
如果string的开始中的零个或多个字符与此正则表达式匹配,则返回相应的MatchObject实例。返回没有如果,则该字符串与模式不匹配请注意这是不同于零长度匹配。
可选pos和endpos参数具有相同的含义,至于search ()方法。
>>> pattern = re.compile("o")
>>> pattern.match("dog") # No match as "o" is not at the start of "dog".
>>> pattern.match("dog", 1) # Match as "o" is the 2nd character of "dog".
<_sre.SRE_Match object at ...>
如果你想要在字符串中的任意位置找到一个匹配,改用search() (请参见search() 与 match())。
类似于finditer()的功能,使用编译后的模式,但也接受可选的pos和endpos参数限制搜索区域像match()。
捕获模式中的组数。
一本字典,由定义任何符号组名称映射(?P < id >)组号码。这本词典是空的如果在模式中使用了无符号的组。
模式字符串中从中重新对象的编译。
Match 对象始终有一个为 True 的布尔值。由于在无法匹配的情况下 match() 和 search() 返回 None ,因此您可以使用简单的 if 语句测试是否有匹配值。
match = re.search(pattern, string)
if match:
process(match)
Match 对象支持下列方法和属性:
返回通过对模板字符串template执行反斜杠替换获得的字符串,和sub()方法的效果一样。Escapes such as \n are converted to the appropriate characters, and numeric backreferences (\1, \2) and named backreferences (\g<1>, \g<name>) are replaced by the contents of the corresponding group.
返回Match对象的一个或多个子组。如果单个参数,结果是一个单一的字符串 ;如果有多个参数,其结果是参数每一项的元组。如果没有参数, group1默认为零 (返回整个match)。如果groupN参数为零,相应的返回值是整个匹配的字符串 ;如果它是在具有包容性的范围 [1..99],它是模式进行相应的括号组匹配的字符串。如果组编号是负值或大于在模式中定义的组的数目,被引发IndexError异常。如果一组包含在模式不匹配的一部分中,相应的结果是没有。如果一组包含在模式匹配多次的一部分,则返回最后一场比赛。
>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
>>> m.group(0) # The entire match
'Isaac Newton'
>>> m.group(1) # The first parenthesized subgroup.
'Isaac'
>>> m.group(2) # The second parenthesized subgroup.
'Newton'
>>> m.group(1, 2) # Multiple arguments give us a tuple.
('Isaac', 'Newton')
如果正则表达式使用(?P < 名称 >...) 语法, groupN参数也可能查明群体按他们的通讯组名称的字符串。如果字符串参数不用作模式中的组名称,被引发IndexError异常。
一个适度复杂的例子:
>>> 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") # Matches 3 times.
>>> m.group(1) # Returns only the last match.
'c3'
返回包含所有匹配到的子组的元组, 从1到模式中的所有组。默认实参用于团体没有参加这场比赛 ;它将默认为None。(不兼容性说明: 在原始的 Python 1.5 版本中,如果元组是一个元素长,字符串将返回相反。在以后的版本中(从1.5.1开始),在这种情况下返回一个单例元组。)
举个例子:
>>> m = re.match(r"(\d+)\.(\d+)", "24.1632")
>>> m.groups()
('24', '1632')
如果我们使小数点和一切在它以后可选,并不是所有的组可能会参加比赛。这些团体将默认为无,除非给出了默认参数:
>>> m = re.match(r"(\d+)\.?(\d+)?", "24")
>>> m.groups() # Second group defaults to None.
('24', None)
>>> m.groups('0') # Now, the second group defaults to '0'.
('24', '0')
返回一个包含所有的比赛,由子组名称键控的命名子群的字典。默认实参用于团体没有参加这场比赛 ;它将默认为None。举个例子:
>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
>>> m.groupdict()
{'first_name': 'Malcolm', 'last_name': 'Reynolds'}
返回的开始和结束的由组; 匹配的子字符串的索引组的默认值为零 (即整个匹配的子字符串)。如果组存在,但却无助于这场比赛将返回-1 。对于一个匹配对象m和做贡献匹配的组g ,由组g (相当于m.group(g)) 匹配的子字符串是
m.string[m.start(g):m.end(g)]
请注意, m.start(group)将等于m.end(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)引发IndexError异常。
将删除的电子邮件地址remove_this的示例:
>>> email = "tony@tiremove_thisger.net"
>>> m = re.search("remove_this", email)
>>> email[:m.start()] + email[m.end():]
'tony@tiger.net'
最后的整数索引匹配捕获组,或没有,如果没有组均在所有匹配。例如,表达式(a) b, ((a)(b)),并且((ab))将有lastindex = = 1如果应用于字符串ab,同时表达(a)(b)将有lastindex = = 2,如果应用到相同的字符串。
最后一次的名称匹配捕获的组,或没有如果小组不是有一个名称,或者如果没有组均在所有匹配。
在这个例子中,我们将使用下面的 helper 函数去更优雅地显示 match 对象:
def displaymatch(match):
if match is None:
return None
return '<Match: %r, groups=%r>' % (match.group(), match.groups())
假设您要编写一个球员手为 5 个字符的字符串代表与代表一张卡,每个字符的扑克程序"a"ace、"k"为国王、 王后、 杰克的"j"、"t"为 10,"q"和"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=()>"
That last hand, "727ak", contained a pair, or two of the same valued cards. 若想以正则表达式匹配它的话,可使用如下反向引用:
>>> 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'
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
Python 提供了两种不同的原始操作基于正则表达式: re.match()检查是否只在字符串的开头匹配而re.search()检查是否在任何地方 (这是默认情况下,Perl 做的) 的字符串匹配。
举个例子:
>>> re.match("c", "abcdef") # No match
>>> re.search("c", "abcdef") # Match
<_sre.SRE_Match object at ...>
正则表达式开头' ^'可以用与search ()来限制进行匹配字符串的开头(“^”表示匹配字符串的开头):
>>> re.match("c", "abcdef") # No match
>>> re.search("^c", "abcdef") # No match
>>> re.search("^a", "abcdef") # Match
<_sre.SRE_Match object at ...>
但是请注意在多行模式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 at ...>
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']]
:?模式匹配在冒号之后的最后一个名称,以便它不出现在结果列表中。与4 maxsplit ,我们可以分开的街道名称门牌号码:
>>> [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']]
sub()替换字符串或函数的结果为每次出现的一种模式。此示例演示如何使用sub()具有功能"伪装"的文本,或随机中每个单词的句子除第一个和最后一个字符之外的所有字符的顺序:
>>> 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.'
search ()一样, findall()匹配所有出现的一种模式,而不仅仅是第一个。举个例子,如果你是一位作家,并且想要寻找一些文本中的副词所有,他或她可能会使用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 string notation (r"text") keeps regular expressions sane. Without it, every backslash ('\') in a regular expression would have to be prefixed with another one to escape it. For example, the two following lines of code are functionally identical:
>>> re.match(r"\W(.)\1\W", " ff ")
<_sre.SRE_Match object at ...>
>>> re.match("\\W(.)\\1\\W", " ff ")
<_sre.SRE_Match object at ...>
当想要匹配文字反斜杠时,必须在正则表达式中先转义。With raw string notation, this means r"\\". Without raw string notation, one must use "\\\\", making the following lines of code functionally identical:
>>> re.match(r"\\", r"\\")
<_sre.SRE_Match object at ...>
>>> re.match("\\\\", r"\\")
<_sre.SRE_Match object at ...>