首页 > 编程知识 正文

史上最全正则表达式,正则表达式高级教程

时间:2023-05-03 09:49:24 阅读:205167 作者:2318

正则表达式 正则表达式的作用:

在实际开发过程中经常会有查找符合某些复杂规则的字符串的需要,比如:邮箱、图片地址、手机号码等,这时候想匹配或者查找符合某些规则的字符串就可以使用正则表达式了。

正则表达式概念

正则表达式就是记录文本规则的代码

正则表达式的特点 正则表达式的语法很令人头疼,可读性差正则表达式通用行很强,能够适用于很多编程语言 re模块的使用过程

在Python中需要通过正则表达式对字符串进行匹配的时候,可以使用一个模块,名字为re

# 导入re模块 import re # 使用match方法进行匹配操作 result = re.match(正则表达式,要匹配的字符串) # 如果上一步匹配到数据的话,可以使用group方法来提取数据 result.group()

注意:re.match() 根据正则表达式从头开始匹配字符串数据

开始进入正题 匹配单个字符 代码功能.匹配任意1个字符(除了n)[ ]匹配[ ]中列举的字符d匹配数字,即0-9D匹配非数字,即不是数字s匹配空白,即 空格,tab键S匹配非空白w匹配非特殊字符,即a-z、A-Z、0-9、_、汉字W匹配特殊字符,即非字母、非数字、非汉字 # . 匹配任意1个字符(除了n)# [ ] 匹配[ ]中列举的字符[ab456c][a-z]# d 匹配数字,即0-9# D 匹配非数字,即不是数字# s 匹配空白,即 空格,tab键t,n# S 匹配非空白# w 匹配单词字符,即a-z、A-Z、0-9、_,国家的文字# W 匹配非单词字符# 匹配任意一个数字# 使用d# 判断用户是否输入的是速度与激情系列import re# print(re.match("速度与激情d", "速度与激情2").group())# print(re.match("速度与激情d", "速度与激情0").group())# print(re.match("速度与激情d", "速度与激情9").group())# print(re.match("速度与激情d", "速度与激情a").group())# 使用[]# 格式1:[单个值,...]# 判断用户只想看1,4,8的速度与激情# print(re.match("速度与激情[148]", "速度与激情1").group())# print(re.match("速度与激情[148]", "速度与激情4").group())# print(re.match("速度与激情[148]", "速度与激情8").group())# print(re.match("速度与激情[148]", "速度与激情9").group())# 格式2:[范围,...]# 判断用户只看1到8的速度与激情# print(re.match("速度与激情[12345678]", "速度与激情1").group())# print(re.match("速度与激情[12345678]", "速度与激情8").group())# print(re.match("速度与激情[1-8]", "速度与激情2").group())# print(re.match("速度与激情[1-8]", "速度与激情8").group())# # print(re.match("速度与激情[1-8]", "速度与激情9").group())# 格式3:[数字字符]# 判断用户输入的速度与激情1到8或者速度与激情风中的纸鹤## print(re.match("速度与激情[1-8]", "速度与激情8").group())# print(re.match("速度与激情[风中的纸鹤]", "速度与激情a").group())# print(re.match("速度与激情[风中的纸鹤]", "速度与激情h").group())# print(re.match("速度与激情[风中的纸鹤]", "速度与激情e").group())# print(re.match("速度与激情[1-8风中的纸鹤]", "速度与激情a").group())# print(re.match("速度与激情[1-8风中的纸鹤]", "速度与激情8").group())# 使用w 即a-z、A-Z、0-9、_这个范围太广,不要轻易用,汉字也可以匹配,其他的国家的语言也可以匹配# 匹配的单词字符# 判断用户输入包含速度与激情# print(re.match("速度与激情w", "速度与激情8").group())# print(re.match("速度与激情w", "速度与激情a").group())# print(re.match("速度与激情w", "速度与激情z").group())# print(re.match("速度与激情w", "速度与激情A").group())# print(re.match("速度与激情w", "速度与激情Z").group())# print(re.match("速度与激情w", "速度与激情_").group())# print(re.match("速度与激情w", "速度与激情好").group())# print(re.match("速度与激情w", "速度与激情あなたのことが好きです").group())## 使用s# --匹配空白字符# --空格 或者 tab(t),n换行# --判断用户速度与激情 8# print(re.match("速度与激情s8", "速度与激情 8").group())# print(re.match("速度与激情s8", "速度与激情t8").group())# print(re.match("速度与激情s8", "速度与激情n8").group())## --大写是所有小写的非*******# .匹配任意1个字符(除了n)# --匹配任意的字符# --判断包含速度与激情字符串的# print(re.match("速度与激情.", "速度与激情tadf").group())# print(re.match("速度与激情.", "速度与激情nadf").group()) 匹配多个字符的相关格式 代码功能*匹配前一个字符出现0次或者无限次,即可有可无+匹配前一个字符出现1次或者无限次,即至少有1次?匹配前一个字符出现1次或者0次,即要么有1次,要么没有{m}匹配前一个字符出现m次{m,n}匹配前一个字符出现从m到n次 # -- 匹配的规则# 字符 功能# * 匹配前一个字符出现0次或者无限次,即可有可无# + 匹配前一个字符出现1次或者无限次,即至少有1次# ? 匹配前一个字符出现1次或者0次,即要么有1次,要么没有# {m} 匹配前一个字符出现m次 d{3}# {m,n} 匹配前一个字符出现从m到n次 d{4,6}# 使用 类型{}# 用来表示一个字符出现多少次# 匹配速度与激情1,速度与激情12import re# print(re.match("速度与激情d", "速度与激情1").group())# print(re.match("速度与激情dd", "速度与激情12").group())# print(re.match("速度与激情d{1,2}", "速度与激情12").group())# print(re.match("速度与激情d{1,2}", "速度与激情1").group())# 匹配手机号11位# print(re.match("d{11}", "12345678901").group())# 判断电话号码是否021 - 开头的后面8位电话号码# 例: 021 - 12345678# 判断电话号# print(re.match("021-d{8}", "021-12345678").group())# 使用?# 用来表示有一个字符或者没有字符# 用户输入的电话号码有时有'-'有时没有# 例:02112345678 或者 021-12345678# print(re.match("021d{8}", "02112345678").group())# print(re.match("021-d{8}", "021-12345678").group())# print(re.match("021-?d{8}", "021-12345678").group())# print(re.match("021-?d{8}", "02112345678").group())### 有些地方是三位电话号码开头,有些是四位电话号码开头# 0571-8123456# 021-12345678# print(re.match("d{3,4}-?d{7,8}", "0571-8123456").group())# print(re.match("d{3,4}-?d{7,8}", "021-12345678").group())# *# 表示0或者无限次# 匹配一段文字或者没有输入文字str = """今天天气不错我们可以出去运动一下!"""# print(re.match(".*", str).group())print(re.match(".*", str, re.S).group()) # re.S这个就是跟.*配合在一起让我们的真正的所有的都能匹配# +# 表示至少一次,不能为空print(re.match(".*", "").group())print(re.match(".+", " ").group()) 匹配开头和结尾的正则表达式 代码功能^匹配字符串开头$匹配字符串结尾[^指定字符]表示除了指定字符都匹配 # [^字符]这个是固定的一个语法,这个意思就是非# 场景hello@163.com hello@163.com,我们想取到第一个邮箱# 如果写字符串有可能会有错,他会去匹配一个字符串出错import restr = "hello@163.com hello@163.com"print(re.match(".{4,20}@163.com", str).group())print(re.match("[^@]+@163.com", str).group())# [^字符]字符 非字符print(re.match("[^bc]", "bc")) 匹配分组相关正则表达式 代码功能|匹配左右任意一个表达式(ab)将括号中字符作为一个分组num引用分组num匹配到的字符串(?P)分组起别名(?P=name)引用别名为name分组匹配到的字符串 # | 相当于python中的or# 案例:匹配出163或者126的邮箱import restr = "hello@163.com"# print(re.match(".{4,20}@(163|126).com", str).group())# ()还可以单独取出匹配的某一部分数据# 案例:取出邮箱的类型(只要163,126),后期可以编计用户那个邮箱用的多# print(re.match(".{4,20}@(163|126).com", str).group(0))# print(re.match("(.{4,20})@(163|126).com", str).group(1))# print(re.match("(.{4,20})@(163|126).com", str).group(2))# print(re.match("(.{4,20})@((163|126).com)", str).group(2))# num用来取第几组用()包裹的数据 1取第一个内部的括号位置的值# 格式(xxx)1 :1表示获取(xxx)的值# 案例<html>hh</html> # 这个一定是有字母,开始跟结束的字母必须一样# str_data = "<html>hh</html> "# print(re.match("<([a-zA-Z]+)>.*</\1>", str_data).group())# 案例<html><body>hh</body></html>str_data = "<html><body>hh</body></html>"# print(re.match("<([a-zA-Z]+)><([a-zA-Z]+)>.*</\2></\1>", str_data).group())# 使用别名给分组取别名,了解一下# 格式:(?P<别名>xxx)(?P=别名)# 案例<html><body>hh</body></html># 提示问题没错print(re.match("<(?P<name1>[a-zA-Z]+)><(?P<name2>[a-zA-Z]+)>.*</(?P=name2)></(?P=name1)>", str_data).group())

注意:(分组数据):分组数是从左到右的方式进行分配的

正则的高级用法 代码功能search不会从头开始匹配,只要匹配到数据就结束findall查询结果集sub将匹配到的数据进行替换split根据匹配进行切割字符串,并返回一个列表 # 查询结果# search 不会从头开始匹配,只要匹配到数据就结束# 案例:匹配出文章阅读的次数中的次数# 数据:"阅读次数为 9999"import re# print(re.search("d+", "阅读次数为 9999").group())# 查询结果集# findall# 案例: 统计出python、c、c + +相应文章阅读的次数# 数据: "python = 9999, c = 7890, c++ = 12345"# print(re.findall("d+", "python = 9999, c = 7890, c++ = 12345"))# 字符串切割# split# 切割字符串“info:xiaoZhang 33 shandong”, 根据:或者空格# print(re.split(":|s", "info:xiaoZhang 33 shandong"))# 替换数据# sub# 案例: 将匹配到的阅读次数换成998# 数据: "python = 997"# re.sub("替换的匹配","想替换成的内容","被替换的内容")str_data = "python = 10000"# 生成一个新的字符# new_data = re.sub("d+", "998", str_data)## print(new_data)# print(str_data)# 通过函数来修改值def change_value(match): # 通过匹配的对象拿到对应的值 value = match.group() # 值加1 count_str = int(value) + 1 return str(count_str) # 必须返回字符串print(re.sub("d+", change_value, str_data)) python贪婪和非贪婪

Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪则相反,总是尝试匹配尽可能少的字符。

r 的作用

Python中字符串前面加上 r 表示原生字符串,数据里面的反斜杠不需要进行转义,针对的只是反斜杠

Python里的原生字符串很好地解决了这个问题,有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。

>>> mm = "c:\a\b\c">>> mm'c:\a\b\c'>>> print(mm)c:abc>>> re.match("c:\\",mm).group()'c:\'>>> ret = re.match("c:\\",mm).group()>>> print(ret)c:>>> ret = re.match("c:\\a",mm).group()>>> print(ret)c:a>>> ret = re.match(r"c:\a",mm).group()>>> print(ret)c:a>>> ret = re.match(r"c:a",mm).group()Traceback (most recent call last): File "<stdin>", line 1, in <module>AttributeError: 'NoneType' object has no attribute 'group'>>>

建议: 如果使用使用正则表达式匹配数据可以都加上r,要注意r针对的只是反斜杠起作用,不需要对其进行转义

>>> ret = re.match(r"c:\a",mm).group()>>> print(ret)c:a

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。