locales 是 C 语言库中的一项功能,是用来为需要考虑不同语言的编程提供帮助的。举个例子,如果你正在处理法文文本,你想用 “w+ 来匹配文字,但 “w 只匹配字符类 [A-Za-z];它并不能匹配 “é” 或 “ç”。如果你的系统配置适当且本地化设置为法语,那么内部的 C 函数将告诉程序 “é” 也应该被认为是一个字母。当在编译正则表达式时使用 LOCALE 标志会得到用这些 C 函数来处理 “w 後的编译对象;这会更慢,但也会象你希望的那样可以用 “w+ 来匹配法文文本。
使用 “^” 只匹配字符串的开始,而 $ 则只匹配字符串的结尾和直接在换行(如果有的话)前的字符串结尾。当指定本标志后, “^” 匹配字符串的开始和字符串中每行的开始。同样的, $ 元字符匹配字符串结尾和字符串中每行的结尾(直接在每个换行之前)。
该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。当该标志被指定时,在 RE 字符串中的空白符被忽略,除非该空白符在字符类中或在反斜杠后面;这可以让你更清晰地组织和缩进re表达式。它也可以允许你将注释写入re表达式,这些注释会被引擎忽略;注释用 “#“号 来标识,不过该符号不能在字符串或反斜杠后面。
import re
s = "life is short, you need Python."
print(re.match(r'life', s)) # 从开始位置能成功匹配到
print(re.match(r'Life', s, re.I)) # 使用re.I标志位来指定忽略大小写
print(re.match(r'life', s).span()) # .span可以获取到具体匹配的起始位置
print(re.match(r'Python', s)) # 从开始位置不能成功匹配到
<_sre.SRE_Match object; span=(0, 4), match='life'>
<_sre.SRE_Match object; span=(0, 4), match='life'>
(0, 4)
对于匹配对象可以使用group(num)和groups()来获取匹配表达式。
group(num=0):匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
groups():返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
import re
s = "life is short, you need Python."
ret = re.match(r'(.*) is (.*)', s)
print("ret.group():", ret.group())
print("ret.group(1, 2):", ret.group(1, 2))
print("ret.group(1):", ret.group(1))
print("ret.group(2):", ret.group(2))
print("ret.groups():", ret.groups())
ret.group(): life is short, you need Python.
ret.group(1, 2): ('life', 'short, you need Python.')
ret.group(1): life
ret.group(2): short, you need Python.
ret.groups(): ('life', 'short, you need Python.')
分组命名匹配:
(?P<分组的名字>正则规则)
**注意:**是大写的P
import re
s = "life is short, you need Python."
ret = re.match(r'(?P<m1>.*) is (?P<m2>.*)', s)
print("ret.group():", ret.group())
print("ret.group('m1'):", ret.group('m1')) # 支持使用组名访问匹配项
print("ret.group('m2'):", ret.group('m2'))
print("ret.group(1, 2):", ret.group(1, 2))
print("ret.group(1):", ret.group(1))
print("ret.group(2):", ret.group(2))
print("ret.groups():", ret.groups())
ret.group(): life is short, you need Python.
ret.group('m1'): life
ret.group('m2'): short, you need Python.
ret.group(1, 2): ('life', 'short, you need Python.')
ret.group(1): life
ret.group(2): short, you need Python.
ret.groups(): ('life', 'short, you need Python.')
re.search
re.search
扫描整个字符串并返回第一个成功的匹配。
re.search(pattern, string, flags=0)
pattern:匹配的正则表达式。
string:要匹配的字符串。
flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
re.search()
方法匹配成功后会返回一个匹配的对象,否则返回None。
import re
s = "life is short, you need Python."
print(re.search(r'life', s))
print(re.search(r'life', s).span())
print(re.search(r'Python', s))
print(re.search(r'Python', s).span())
print(re.search(r'xxx', s))
<_sre.SRE_Match object; span=(0, 4), match='life'>
(0, 4)
<_sre.SRE_Match object; span=(24, 30), match='Python'>
(24, 30)
同样可以使用group(num)
或groups()
来获取匹配表达式。
import re
s = "life is short, you need Python."
ret = re.search(r'(.*) is (.*)', s)
print(ret.group())
print(ret.group(1, 2))
print(ret.group(1))
print(ret.group(2))
print(ret.groups())
life is short, you need Python.
('life', 'short, you need Python.')
short, you need Python.
('life', 'short, you need Python.')
re.match和re.search的区别:
re.match
只匹配字符串的开始,如果字符串的开始位置不符合正则表达式,则匹配失败,函数返回None;而re.search
匹配整个字符串,直到找到一个匹配,整个字符串都找不到匹配才返回None。
re.split
用匹配到的对象将字符串分割成列表并返回。
re.split(pattern, string, maxsplit=0, flags=0)
pattern:匹配的正则表达式。
string:要匹配的字符串。
maxsplit:模式匹配后分割的最大次数,默认 0 表示分割所有的匹配。
flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
import re
s = "Abc123.aBc456.abC789"
ret1 = re.split(r'\.', s) # 用.分割字符串s
ret2 = re.split(r'\.', s, 1) # 用.分割字符串s,只分割一次
ret3 = re.split(r'[.\d]+', s) # 用.和数字分s
print("用.分割字符串s:", ret1)
print("用.分割字符串s,只分割一次:", ret2)
print("用.和数字分s:", ret3)
用.分割字符串s: ['Abc123', 'aBc456', 'abC789']
用.分割字符串s,只分割一次: ['Abc123', 'aBc456.abC789']
用.和数字分s: ['Abc', 'aBc', 'abC', '']
当正则匹配项位于字符串的开头或结尾时,re.split()
得到列表会有空元素。
re.findall
找到字符串中所有的匹配项,以列表的形式返回。
re.findall(pattern, string, flags=0)
pattern:匹配的正则表达式。
string:要匹配的字符串。
flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
import re
s = "Abc123.aBc456.abC789"
ret = re.findall(r'\d+', s) # 找到所有的连续数字,并以列表形式返回
print("所有的数字:", ret)
所有的数字: ['123', '456', '789']
re.sub
re.sub
用来替换字符串中的匹配项。
re.sub(pattern, repl, string, count=0, flags=0)
pattern:匹配的正则表达式。
repl:替换的字符串,也可为一个函数。
string:要被查找替换的原始字符串。
count:模式匹配后替换的最大次数,默认 0 表示替换所有的匹配。
flags:标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
import re
s = "life is short, you need Python. # 人生苦短,我用Python。"
# 删除#及后面的内容(把#及后面的字符替换成空字符串)
s1 = re.sub(r'#.*$', "", s)
print("去掉注释后:", s1)
去掉注释后: life is short, you need Python.
示例2(当repl
参数是一个函数时):
import re
# 将匹配的数字乘于2
def double(matched):
num = int(matched.group("num")) # 注意要转成int类型
return str(num * 2) # 将乘以2后的结果转成str类型
s = "1 + 2 = 3"
s1 = re.sub(r'(?P<num>\d+)', double, s) # 分组命名匹配
print("re.sub替换后:", s1)
re.compile
将正则表达式模式编译为正则表达式对象,可用于使用其match()
和search()
方法进行匹配,如下所述。
re_obj = re.compile(pattern)
ret = re_obj.match(string)
ret = re.match(pattern, string)
正则表达式练习
匹配手机号
ret = re.match(r'(1)[3578]\d{9}', s)
ret = re.match(r'^([a-z.0-9]{1,26})@([a-z.0-9]{1,20})(.[a-z0-9]{1,8})$', s)
ret = re.match(r'^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$', s)