1. match方法
re.match
尝试从字符串起始位置匹配一个模式,如果不是起始位置匹配成功的话,match
就返回None
。语法格式如下:
-
re.match(pattern, string, flags=0)
pattern
:匹配的正则表达式string
:要匹配的字符串flags
:标志位,用于控制正则表达式的匹配方式
-
标志位:
修饰符 描述 re.I
忽略大小写 re.L
做本地化(locale-aware)匹配 re.M
多行匹配,影响 ^
和$
re.S
使 .
匹配包括换行符在内的所有字符re.U
根据Unicode字符集解析字符。这个标志影响 \w
,\W
,\b
,\B
re.X
该标志通过给予你更灵活的方式以便你将表达式写的更易于理解
match
方法的使用
import re
s = "hello world"
pattern = "hello"
rs = re.match(pattern, s)
print(rs)
# <re.Match object; span=(0, 5), match='hello'>
print(dir(rs)) # 查看rs的方法
# ['__class__', '__copy__', ..., 'pos', 're', 'regs', 'span', 'start', 'string']
print(rs.group()) # 返回s中匹配到的字符串
# hello
print(rs.span()) # 返回s中匹配到的范围
# (0, 5)
print(rs.start()) # 返回s中匹配到的字符串起始位置
# 0
2. 常用匹配符
符号 | 描述 |
---|---|
. |
匹配除换行符\n 以外任意一个字符 |
[] |
匹配列表中的字符 |
\w |
匹配字母、数字、下划线,即 a-z,A-Z,0-9,_ |
\W |
匹配不是字母、数字、下划线的字符 |
\s |
匹配空白字符,即空格(\n ,\t ) |
\S |
匹配不是空白的字符 |
\d |
匹配数字,即 0-9 |
\D |
匹配非数字的字符 |
s_list = ["1", "6", "D", "\t", "a", "\n", "_", "."]
# --------------- "."的使用 --------------- #
print([re.match(".", s) is not None for s in s_list]) # 除\n以外任意字符
# [True, True, True, True, True, False, True, True, True, True, True]
# --------------- "[]"的使用 --------------- #
print([re.match("[0-9a-z]", s) is not None for s in s_list]) # 数字和小写字母
# [True, True, False, False, True, False, False, False, False, False, False]
# --------------- "\w"的使用 --------------- #
print([re.match("\w", s) is not None for s in s_list]) # a-z A-Z 0-9 _
# [True, True, True, False, True, False, True, False, False, False, False]
# --------------- "\W"的使用 --------------- #
print([re.match("\W", s) is not None for s in s_list]) # 除a-z A-Z 0-9 _以外的字符
# [False, False, False, True, False, True, False, True, True, True, True]
# --------------- "\s"的使用 --------------- #
print([re.match("\s", s) is not None for s in s_list]) # 空白字符\t \n等
# [False, False, False, True, False, True, False, False, False, False, False]
# --------------- "\d"的使用 --------------- #
print([re.match("\d", s) is not None for s in s_list]) # 数字
# [True, True, False, False, False, False, False, False, False, False, False]
3. 限定符
符号 | 描述 | 符号 | 描述 |
---|---|---|---|
* |
匹配0次或多次 | {m} |
重复m次 |
+ |
匹配一次或多次 | {m,n} |
重复m到n次 |
? |
匹配一次或0次 | {m,} |
至少m次 |
s_list = ["123qwe", "qwerty", "1qwe", "12345"]
# --------------- "*"的使用 --------------- #
print([re.match("\d*", s) is not None for s in s_list]) # 匹配0个或多个数字
# [True, True, True, True]
# --------------- "+"的使用 --------------- #
print([re.match("\d+", s) is not None for s in s_list]) # 匹配一个或0个数字
# [True, False, True, True]
# --------------- "?"的使用 --------------- #
print([re.match("\d?", s) is not None for s in s_list]) # 匹配一个或0个数字
# [True, True, True, True]
# --------------- "{m}"的使用 --------------- #
print([re.match("\d{3}", s) is not None for s in s_list]) # 匹配3个数字
# [True, False, False, True]
# --------------- "{m,n}"的使用 --------------- #
print([re.match("\d{2,5}", s) is not None for s in s_list]) # 匹配2到3个数字
# [True, False, False, True]
# --------------- "{m,}"的使用 --------------- #
print([re.match("\d{3,}", s) is not None for s in s_list]) # 至少3个数字
# [True, False, False, True]
4. 边界字符
字符 | 功能 |
---|---|
^ |
匹配开头 |
$ |
匹配结尾 |
\b |
匹配单词边界 |
\B |
匹配非单词边界 |
[^] |
匹配除列表中指定字符以外的所有字符 |
# --------------- "$"用法,匹配QQ邮箱 --------------- #
# 5-10位数字,@qq.com结尾
pattern = r"[1-9]\d{4,9}@qq.com$"
match_list = ["318821221@qq.com", "a31234@qq.com", "123.231@qq.com", "3123213@163.com", "3127721@qq.com.cn"]
print([bool(re.match(pattern, s)) for s in match_list])
# [True, False, False, False, False]
# --------------- "^"匹配开头 --------------- #
pattern = r"^hello.*"
match_list = ["hello python", "hi python"]
print([bool(re.match(pattern, s)) for s in match_list])
# [True, False]
# --------------- "\b"匹配单词左边界 --------------- #
pattern = r".*\bab"
match_list = ["12345 abc", "baby", "absolute", "stab"]
print([bool(re.match(pattern, s)) for s in match_list])
# [True, False, True, False]
# --------------- "\b"匹配单词右边界 --------------- #
pattern = r".*ab\b"
match_list = ["12345 abc", "baby", "absolute", "stab"]
print([bool(re.match(pattern, s)) for s in match_list])
# [False, False, False, True]
# --------------- "\B"匹配非单词边界 --------------- #
pattern = r".*\Bab" # 非ab开头
match_list = ["12345 abc", "baby", "absolute", "stab"]
print([bool(re.match(pattern, s)) for s in match_list])
# [False, True, False, True]
5. search方法
search
与mactch
的区别:
re.match()
只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None
;- 而
re.search()
匹配整个字符串,直到找到一个匹配。
pattern = r"Love"
s = "I Love You"
print(re.match(pattern, s))
# None
print(re.search(pattern, s))
# <re.Match object; span=(2, 6), match='Love'>
6. 匹配多个字符串
search()
方法搜索一个字符串,想要搜索多个字符串,使用择一匹配符号 |
。择一匹配符号和逻辑或类似,只要满足任何一个,就算匹配成功。
pattern = r"aa|bb|cc"
s = "my name is cc"
print(re.search(pattern, s))
# <re.Match object; span=(11, 13), match='cc'>
# --------------- 匹配0-100之间的所有数字 --------------- #
pattern = r"[1-9]?\d$|100$"
s_list = ["1", "0", "63", "121", "100", "9218", "010"]
print([bool(re.match(pattern, s)) for s in s_list])
# [True, True, True, False, True, False, False]
对于单个字符使用或关系时,使用字符集 []
和择一匹配符 |
的效果是相同的。
pattern = r"[ab][cd]"
s_list = ["ab", "ac", "bd", "cd", "ad"]
print([bool(re.match(pattern, s)) for s in s_list])
# [False, True, True, False, True]
# 等同于
pattern = r"ac|ad|bc|bd"
print([bool(re.match(pattern, s)) for s in s_list])
# [False, True, True, False, True]
7. 分组
我们可以用小括号()
来进行分组,括起来的部分会成为一组,通过group()
方法的参数获取指定的组匹配的字符串。
字符 | 功能 |
---|---|
(ab) |
对括号内的字符进行分组 |
\num |
引用分组num 匹配到的字符串 |
(?P<name>) |
分别起组名 |
(?P=name) |
引用别名为name 分组匹配到的字符串 |
8. sub和subn搜索与替换
sub
和subn
用于实现搜索和替换功能。这两个函数的功能几乎完全相同,都是将字符串所匹配正则表达式的部分替换成其他字符串。用于替换的部分可以使一个字符串,也可以是一个返回字符串的函数。
sub
函数返回替换后的结果;subn
函数返回一个由替换后的字符串和替换的总数组成的元组。
re.sub(pattern, repl, string, count=0, flags=0)
:pattern
:匹配的正则表达式repl
:替换的字符串,也可以是一个返回字符串的函数string
:被替换的原始字符串count
:模式匹配后替换的最大次数,默认0表示替换所有的匹配flags
:标志位,用于控制正则表达式的匹配方式
phone = "2004-959-559 # 这是一个国外电话号码"
# --------------- 删除字符串中的注释 --------------- #
num = re.sub(r"#.*$", "", phone)
# 2004-959-559
# --------------- 删除除电话号码以外的所有字符 --------------- #
num = re.sub(r"\D", "", phone)
# 2004959559
# --------------- subn删除除电话号码以外的所有字符 --------------- #
result = re.subn(r"\D", "", phone)
# ('2004959559', 16)
9. compile方法
compile()
方法用于编译正则表达式,生成一个正则表达式(Pattern)对象,供match()
和search()
这两个函数使用。语法格式为:
re.compile(pattern[, flags])
:pattern
:一个字符串形式的正则表达式flags
:可选,标志位,用于控制正则表达式的匹配方式
# --------------- compile的使用 --------------- #
s = "first123 line"
regex = re.compile(r"\w+")
print(regex.match(s))
10. findall方法和finditer方法
-
findall()
方法在字符串中找到正则表达式所匹配的所有字符串,并返回一个列表,如果没找到匹配子串则返回空列表。语法格式如下:findall(pattern, string, flags=0)
:pattern
:匹配的正则表达式string
:要匹配的字符串
# --------------- findall的使用 --------------- # s = "first 1 second 2 third 3" rs = re.findall(r"\w+", s) print(rs) # ['first', '1', 'second', '2', 'third', '3']
-
finditer()
方法与findall
类似,只不过finditer()
返回的是一个迭代器对象,获取匹配到的字符串时需要遍历并调用item.group()
方法。# --------------- finditer的使用 --------------- # s = "first 1 second 2 third 3" iterator = re.finditer(r"\w+", s) print(iterator) # <callable_iterator object at 0x7fd7129696d0> for item in iterator: print(item.group(), end="\t") # first 1 second 2 third 3
11. split方法
split()
方法用于根据正则表达式分割字符串,它返回一个分割后的子串列表。
re.split(pattern, string[, maxsplit=0, flags=0])
:pattern
:要匹配的表达式string
:要匹配的字符串maxsplit
:最大分割次数,默认为0,即不限制
# --------------- split的使用 --------------- #
s = "first 1 second 2 third 3"
# 按数字分割
print(re.split(r"\d+", s))
# ['first ', ' second ', ' third ', '']
# 指定maxsplit=1
print(re.split(r"\d+", s, maxsplit=1))
# ['first ', ' second 2 third 3']
12. 贪婪模式与非贪婪模式
在Python中正则匹配默认是贪婪的,总是尝试匹配尽可能多的字符。非贪婪模式则是尽可能少的匹配字符可以使用*
,?
,+
,{m,n}
后面加 ?
使得贪婪匹配变为非贪婪匹配。
-
例1:
# --------------- 贪婪模式 --------------- # rs = re.match(r"(.+)(\d+-\d+-\d+)", "This is my tel: 133-1234-1234") print(rs.group(1)) # This is my tel: 13 print(rs.group(2)) # 3-1234-1234 # --------------- 非贪婪模式 --------------- # rs = re.match(r"(.+?)(\d+-\d+-\d+)", "This is my tel: 133-1234-1234") print(rs.group(1)) # This is my tel: print(rs.group(2)) # 133-1234-1234
-
例2:
# --------------- 贪婪模式 --------------- # rs = re.match(r"abc(\d+)", "abc123") print(rs.group(1)) # 123 # --------------- 非贪婪模式 --------------- # rs = re.match(r"abc(\d+?)", "abc123") print(rs.group(1)) # 1