python re 的使用
文章目录
- python re 的使用
- 语法规则
- re.compile(pattern, flags=0)
- re.search(pattern, string, flags=0)
- re.match(pattern, string, flags=0)
- search() vs match()
- re.fullmatch(pattern, string, flags=0)
- re.split(pattern, string, maxsplit=0, flags=0)
- re.findall(pattern, string, flags=0)
- re.sub(pattern, repl, string, count=0, flags=0)
- re.escape(pattern)
语法规则
字符匹配
在正则表达式中,如果直接给出字符,就是精确匹配。
\d 匹配一个数字
\D 匹配一个非数字
\w 匹配一个字母、数字或下划线_
\W 匹配任何非单词字符, 等价于“[ ^ A-Za-z0-9_]"
\s 匹配任何空白字符,包括空格、制表符、换页符等等, 等价于[f\n\r\t\v]
\S 匹配任何非空白字符
\n 匹配一个换行符
\r 匹配一个回车符
\t 匹配一个制表符
\A 只匹配字符串开始。
\b 匹配空字符串,但只在单词开始或结尾的位置。
数量匹配
.匹配除“\n"之外的任何单个字符
*匹配前面的子表达式零次或多次
+匹配前面的子表达式一次或多次
?匹配前面的子表达式零次或一次
*?, +?, ??'*', '+',和 '?' 修饰符都是 贪婪的;它们在字符串进行尽可能多的匹配。
(?=…) 匹配 … 的内容,但是并不消费样式的内容。Isaac (?=Asimov) 匹配 'Isaac ' 只有在后面是 'Asimov' 的时候。
{n},n是一个非负整数,匹配确定的n次
{n, m},m和n均为非负整数,其中n <= m,最少匹配n次且最多匹配m次
{n, },n是一个非负整数,至少匹配n次
{, m} 匹配前面的正则表达式最多m次
范围匹配
[xyz] 字符集合, 匹配所包含的任意一个字符
[ ^ xyz] 负值字符集合, 匹配未包含的任意字符
[a-z] 字符范围, 匹配指定范围内的任意字符
[ ^ a-z] 负值字符范围, 匹配任何不在指定范围内的任意字符[0-9a-zA-Z\_]可以匹配一个数字、字母或者下划线;
[0-9a-zA-Z\_]+可以匹配至少由一个数字、字母或者下划线组成的字符串,比如'a100','0_Z','Py3000'等等;
[a-zA-Z\_][0-9a-zA-Z\_]*可以匹配由字母或下划线开头,后接任意个由一个数字、字母或者下划线组成的字符串,也就是Python合法的变量;
[a-zA-Z\_][0-9a-zA-Z\_]{0, 19}更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)。
A | B可以匹配A或B,所以(P | p)ython可以匹配'Python'或者'python'。
^表示行的开头,^\d表示必须以数字开头。
$表示行的结束,\d$表示必须以数字结束。
python flags
re.I 使匹配对大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配,影响 ^ 和 $
re.S 使 . 匹配包括换行在内的所有字符
re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。
re.compile(pattern, flags=0)
将正则表达式的样式编译为一个 正则表达式对象
简单案例
s="123WWqw4wweEEd"
r=re.compile(r'1\d+w')
print(r.match(s))
r=re.compile(r'1\d+w',flags=re.I)
print(r.match(s).group()) 返回匹配的字符串部分
print(r.match(s).span()) 返回包含匹配的开始和结束位置的元组。
print(r.match(s).start())
print(r.match(s).end())
print(r.match(s).string) 返回传递给函数的字符串
验证IP
r = re.compile(r'^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$')
print(r.match("192.168.100.1"))
print(r.match("192.168.1009.111"))
print(r.match("192.168.100.256")
re.search(pattern, string, flags=0)
扫描整个 字符串 找到匹配样式的第一个位置,并返回一个相应的 匹配对象。
简单案例
s = '1102231990xxxxx xxx'
res = re.search('(?P<province>\d{3})(?P<city>\d{3})(?P<born_year>\d{4})', s)
print(res.groupdict())
print(res.group('city'))
print(res.group())
print(res.group(1))
print(re.search("\w",s))
print(re.search("\b",s))
print(re.search("\s",s))
匹配标签
r = re.search("<(?P<tag_name>\w+)>(\w+)</(?P=tag_name)>", "<div>hello</div>")
print(r.group('tag_name'))
print(r.group())
r = re.search(r"<(\w+)>(\w+)</\1>", "<h1>hello</h1>") 可以用\序号来找到对应的组
print(r.group(1))
print(r.group(2))
re.match(pattern, string, flags=0)
如果整个 string 匹配到正则表达式样式,就返回一个相应的 匹配对象
简单案例
print(re.match(r'\d+','12'))
print(re.match(r'\d+','w12'))
匹配时间
result = re.match(r'^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:([0-5]?[0-9])\:([0-5]?[0-9])$', '11:24:59')
print("yes") if result else print("no")
print(result.group())
print(result.groups())
匹配邮箱
email = 'X242599999jack3@xiaoxiaoran.com'
pattern = r'^[a-zA-Z]\w+@xiaoxiaoran.com$'
result = re.match(pattern, email)
print("yes") if result else print("no")
匹配url
url="http://xiaoxiaoran.top"
pattern=r'(http|https)://\S+'
result=re.match(pattern,url)
print("yes") if result else print("no")
search() vs match()
基于 re.match() 检查字符串开头,或者 re.search() 检查字符串的任意位置
print(re.match(r"c","abc"))
print(re.search(r"c","abc"))
re.fullmatch(pattern, string, flags=0)
如果整个 string 匹配到正则表达式样式,就返回一个相应的 匹配对象
print(re.fullmatch(r'<>1\d+','<>1111'))
print(re.fullmatch(r'<>1\d+','<>1111w'))
匹配汉字
print(re.fullmatch(r'^[\u4e00-\u9fa5]{0,}$', "肖萧然"))
print(re.fullmatch(r'^[\u4e00-\u9fa5]{0,}$',"1w"))
匹配密码
由数字/大写字母/小写字母/标点符号组成,四种都必有,8位以上)
print(re.fullmatch(r'(?=^.{8,}$)(?=.*\d)(?=.*\W+)(?=.*[A-Z])(?=.*[a-z])(?!.*\n).*$',"@xX2345678"))
re.split(pattern, string, maxsplit=0, flags=0)
用 pattern 分开 string 。 如果在 pattern 中捕获到括号,那么所有的组里的文字也会包含在列表里
简单案例
print(re.split(r'\d+','w1m2n2j32'))
print(re.split(r'\d+', 'w1m2n2j32', maxsplit=2))
print(re.split(r'\d+', 'w1m2n2j32', flags=re.IGNORECASE))
re.findall(pattern, string, flags=0)
返回string中模式的所有非重叠匹配,作为字符串或元组的列表。从左到右扫描字符串,并按找到的顺序返回匹配项。
print(re.findall(r'\bf[a-z]*',"frr efdd fee fww123"))
print(re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10'))
print(re.findall(r"f","fjfjfjfjfj"))
print(re.findall(r"f666","fjfjfjfjfj"))
匹配数字
print(re.findall(r"-?\d+\.\d+|\d+", "1-2*(60+(-40.35/5)-(-4*3))"))
print(re.findall(r"[+,*,/,-]", "1-2*(60+(-40.35/5)-(-4*3))"))
re.sub(pattern, repl, string, count=0, flags=0)
返回通过使用 repl 替换在 string 最左边非重叠出现的 pattern 而获得的字符串。 如果样式没有找到,则不加改变地返回 string。
str="1we23we23ewew3w"
print(re.sub("\d", "(っ °Д °;)っ", str))
print(re.sub("\d", " ", str))
print(re.sub("\d", "(っ °Д °;)っ", str, 1))
print(re.sub("\d", "-", str, 2))
截取标签
s = "<div class='a'>正则<span>表达式</span><b style='color:red'>练习</b></div>"
ret = re.sub(r'(</?div.*?>|</?b.*?>|</?span>)', '', s)
print(ret)
re.escape(pattern)
转义 pattern 中的特殊字符。
import string
print(re.escape(string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:"))