正则表达式

正则表达式定义和作用

  1. 正则表达式的定义: 是约束字符串匹配某种形式的规则
  2. 正则表达式的作用:
    1. 检测某个字符串是否符合规则
    2. 提取网页字符串中想要的数据

正则表达式所包含的元素种类

正则表达式由一些 [普通字符] 和一些 [元字符] 组成

  1. 普通字符: 包括大小写字母和数字
  2. 元字符 具有特殊含义 , 大体种类分为如下:
    1. 预定义字符集,字符组
    2. 量词
    3. 边界符
    4. 分组

元字符

元字符的种类: 1. 预定义字符集 , 字符组 2. 量词 3. 边界符 4. 分组

1. 单个字符的匹配

import re => 导入正则表达式模块

findall(正则表达式,字符串) 把符合正则表达式的字符串存在列表当中返回

**语法结构: re.findall(正则表达式,字符串) **

预定义字符集

. 匹配任意字符 , 除了换行符 \n

[] 匹配中括号内列举的字符

\d 匹配数字

import restrvar = "skj9fd8l7kas456fl(_)*/&%#123"
lst = re.findall("\d",strvar)
print(lst)

\D 匹配非数字

strvar = "skj9fd8l7kas456fl(_)*/&%#123"
lst = re.findall("\D",strvar)
print(lst)

\w 匹配字母或数字或下划线 (正则函数中,支持中文的匹配)

strvar = "你好skj9fd8l7k_as456fl(_)*/&%#123"
lst = re.findall("\w",strvar)
print(lst)

\W 匹配非字母或数字或下划线

strvar = "你好skj9fd8l7k_as456fl(_)*/&%#123"
lst = re.findall("\W",strvar)
print(lst)

\s 匹配任意的空白符 ( \n \t \r ’ ’ )

strvar = "       \r    "
lst = re.findall("\s",strvar)
print(lst)

\S 匹配任意非空白符

strvar = "       abc         "
lst = re.findall("\S",strvar)
print(lst)

\n 匹配一个换行符

strvar = """"""
lst = re.findall(r"\n",strvar)
print(lst)

\t 匹配一个制表符

strvar = """"""
lst = re.findall(r"\t",strvar)
print(lst)

字符组 []

字符组 [] 必须从字符组列举出来的字符当中抽取,默认一个,如果没有返回空

字符组格式:

[…] 匹配字符组中的字符

[^…] 匹配除了字符组内所有内容 , 之外的所有字符

strvar = "asdhiofdskl"
lst = re.findall("[abcd]",strvar)
print(lst) # ['a', 'd', 'd']# 练习
print(re.findall("a[abc]b","aab abb acb adb")) # aab abb acb
print(re.findall('a[0123456789]b','a1b a2b a3b acb ayb')) # a1b a2b a3b # "-" 代表到 , 代表的范围
# 0-9 => 0到9 <=> 0 1 2 3 4 5 6 7 8 9
print(re.findall('a[0-9]b','a1b a2b a3b acb ayb')) # a1b a2b a3b # a-g <=> a b c d e f g
print(re.findall('a[abcdefg]b','a1b a2b a3b acb ayb adb')) # acb adb
print(re.findall('a[a-g]b','a1b a2b a3b acb ayb adb'))     # acb adb
# a-z <=> 26个小写字母
print(re.findall('a[a-z]b','a1b a2b a3b acb ayb adb')) # acb ayb adb# A-G <=> ABCDEFG
print(re.findall('a[ABCDEFG]b','a1b a2b a3b  aAb aDb aYb')) #aAb aDb
print(re.findall('a[A-G]b','a1b a2b a3b  aAb aDb aYb'))     #aAb aDb
# A-Z <=> 26个大写字母
print(re.findall('a[A-Z]b','a1b a2b a3b  aAb aDb aYb')) #aAb aDb aYb
print(re.findall('a[0-9a-zA-Z]b','a-b aab aAb aWb aqba1b')) # aab aAb aWb aqb a1b# 0-z 不会单纯的匹配大小写字母和数字,还会匹配到特殊的符号,比如 _ @
print(re.findall('a[0-z]b','a_ba@b aab aAb aWb aqba1b')) # a_b a@b aab aAb aWb aqb a1b
print(re.findall('a[0-9][*#/]b','a1/b a2b a29b a56b a456b')) #a1/b# "^" 匹配除了字符组内所有内容,之外的所有字符,在字符组当中开头的位置使用
print(re.findall('a[^-+*/]b',"a%b ccaa*bda&bd")) #a%b a&b# 如果想要匹配 ^ - 需要在前面加上 \ 进行转义
lst = re.findall("a[\^\-]b","a+b a-b a^b")
print(lst) # ['a-b', 'a^b']# 匹配 \
""" \b 本身也是转义字符 : 退格 (把光标向左移动一位) """
lst = re.findall(r"a\\b",r"a\b")
print(lst[0]) # a\b

2. 多个字符的匹配

量词

  1. ? 匹配0个或者1个a

    print(re.findall('a?b','abbzab abb aab'))  # ab b ab ab b ab
    
  2. + 匹配1个或者多个a

    print(re.findall('a+b','b ab aaaaaab abb')) # ab aaaaaab ab
    
  3. * 匹配0个或者多个a

    print(re.findall('a*b','b ab aaaaaab abbbbbbb')) # b ab aaaaaab ab b b b b b b
    
  4. {n} 匹配n次a

    # {2} 必须两次
    print(re.findall('a{2}b','aaab ab aab abbb aaz aabb')) # aab aab aab
    

    {n,} 匹配n次或更多次a

    # {2,} 至少两次
    print(re.findall('a{2,}b','aaab ab aab abbb aaz aabb')) # aaab aab aab
    

    {m,n} 匹配m到n次a

    # 1 <= x <= 3
    print(re.findall('a{1,3}b','aaab ab aab abbb aaz aabb')) # aaab ab aab ab aab
    

3. 贪婪匹配和非贪婪匹配

贪婪匹配

贪婪匹配: 默认向更多次数匹配 (回溯算法)

回溯算法: 从左向右进行匹配 , 直到匹配到最后 , 再也找不到了 , 回头 , 找最后一个 (递归)

strvar = "刘能和刘老根和刘大脑袋111袋222"
lst = re.findall("刘.",strvar)
print(lst) # ['刘能', '刘老', '刘大']lst = re.findall("刘.?",strvar)
print(lst) # ['刘能', '刘老', '刘大']lst = re.findall("刘.+",strvar)
print(lst) # ['刘能和刘老根和刘大脑袋111袋222']lst = re.findall("刘.*",strvar)
print(lst) # ['刘能和刘老根和刘大脑袋111袋222']lst = re.findall("刘.{4,}袋",strvar)
print(lst) # ['刘能和刘老根和刘大脑袋111袋']

非贪婪匹配

非贪婪匹配: 默认向更少次数匹配

语法结构: 在量词后面接 ? 比如: .?? .+? .*? {4,}?

. 匹配任意字符 , 除了换行符 \n

strvar = "刘能和刘老根和刘大脑袋111袋222"lst = re.findall("刘.??",strvar)
print(lst) # ['刘', '刘', '刘']lst = re.findall("刘.+?",strvar)
print(lst) # ['刘能', '刘老', '刘大']lst = re.findall("刘.*?",strvar)
print(lst) # ['刘', '刘', '刘']lst = re.findall("刘.{4,}?袋",strvar)
print(lst) # ['刘能和刘老根和刘大脑袋']

4. 边界符 \b ^ $

\b: 匹配一个字符的边界

\b 本身是转义字符 : 退格(把光标向左移动一位)

​ 例. word :

右边界: d\b

左边界: \bw

  1. 右边界

    strvar = "word pwd scf"
    lst = re.findall(r"d\b",strvar)
    print(lst) # ['d','d']lst = re.findall(r".*d\b",strvar)print(lst) # ['word pwd']lst = re.findall(r".*?d\b",strvar)print(lst) # ['word' , 'pwd']
    
  2. 左边界

    strvar = "word pwd scf"
    lst = re.findall(r"\bw",strvar)
    print(lst) # ['w']# 要所有w开头的单词
    lst = re.findall(r"\bw.*",strvar)
    print(lst) # ['word pwd scf']lst = re.findall(r"\bw.*?",strvar)
    print(lst) # ['w']lst = re.findall(r"\bw.* ",strvar)
    print(lst) # ['word pwd ']lst = re.findall(r"\bw.*? ",strvar)
    print(lst) # ['word ']# \S 匹配的是非空白符lst = re.findall(r"\bw\S*",strvar)
    print(lst) # ['word']
    

^ : 匹配字符串的开始 (必须以… 开头)

$ : 匹配字符串的结尾 (必须以… 结尾)

注意: 当使用 ^ 和 $ 符号的时候 , 要把字符串看成整体

strvar = "大哥大嫂大爷"
print(re.findall("大.",strvar))       # ['大哥', '大嫂', '大爷']
print(re.findall("^大.",strvar))      # ['大哥']
print(re.findall("大.$",strvar))      # ['大爷']
print(re.findall("^大.$",strvar))     # []
print(re.findall("^大.*?$",strvar))   # ['大哥大嫂大爷']
print(re.findall("^大.*?大$",strvar)) # []
print(re.findall("^大.*?爷$",strvar)) # ['大哥大嫂大爷']print(re.findall('^g.*? ' , 'giveme 1gfive gay')) # giveme
print(re.findall('five$' , 'aassfive'))           # five
print(re.findall('^giveme$' , 'giveme'))          # giveme
print(re.findall('^giveme$' , 'giveme giveme'))   # []
print(re.findall('giveme' , 'giveme giveme'))     # giveme giveme
print(re.findall("^g.*e",'giveme 1gfive gay'))    # giveme 1gfive

5. 分组

分组 用法说明
a|b 匹配字符a 或 字符b
(ab) 匹配括号内的表达式 , 将()作为一个分组
\num 引用分组num匹配到的字符串
(?P<name>) 给分组命名
(?P=name) 引用别名: 把name分组所匹配到的内容引用到这里

正常分组 ()

  1. 正常情况下用 () 圆括号进行分组 , 可以用 \1 反向引用第一个圆括号匹配到的内容

  2. (? : 正则表达式) 表示取消优先显示的功能

    (正则表达式) 代表分组 findall 把所有分组的内容显示到列表里

    (? : 正则表达式) 代表分组 findall 把所有分组的内容不显示到列表里

匹配分组

# 分组练习 (用圆括号)# 常规用法
print(re.findall('.*?_good','wusir_good alex_good secret男_good'))
# ['wusir_good', ' alex_good', ' secret男_good']# () 优先显示括号里面的内容
print(re.findall('(.*?)_good','wusir_good alex_good secret男_good'))
# ['wusir', ' alex', ' secret男']# ?: 取消显示括号里面的内容
print(re.findall('(?:.*?)_good','wusir_good alex_good secret男_good'))
# ['wusir_good', ' alex_good', ' secret男_good']

| 代表或 , 在使用 | 的时候 , 把不容易匹配到的字符串放在前面,把容易匹配到的放在后面

strvar = "abcdefg"
lst = re.findall("a|b",strvar)
print(lst) # ['a', 'b']strvar = "abckdfdsfsdfabcdsklda"
lst = re.findall("abc|abcd",strvar)
print(lst) # ['abc', 'abc']
lst = re.findall("abcd|abc",strvar)
print(lst) # ['abc', 'abcd']# 练习1
"""
. 除了\n , 匹配所有字符
\. 代表的 . 这个字符本身 , 不转义
"""
strvar = ".12 ....45.   21.12 47.9 .8 .4 .2 "# 匹配小数
lst = re.findall(r"\d+\.\d+",strvar)
print(lst) # ['21.12', '47.9']# 匹配小数和整数
lst = re.findall(r"\d+\.\d+|\d+",strvar)
print(lst) # ['12', '45', '21.12', '47.9', '8', '4', '2']# 分组表达小数和整数
lst = re.findall(r"\d+(\.\d+)?",strvar)
print(lst) # ['', '', '.12', '.9', '', '', '']lst = re.findall(r"\d+(?:\.\d+)?",strvar)
print(lst) # ['12', '45', '21.12', '47.9', '8', '4', '2']# 练习2 匹配135或171的手机号
strvar = "13603571111 13503578888 17021900921 17109212190"
lst = re.findall(r"(?:135|171)\d{8}",strvar)
print(lst) # ['13503578888', '17109212190']# 用 ^ $ 卡死长度,只能是一个手机号,不能是多个
strvar = "17109212190"
lst = re.findall(r"^(?:135|171)\d{8}$",strvar)
print(lst) # ['17109212190']"""
findall  是把所有符合条件的内容都匹配出来,放到列表里不能够把匹配到的结果和分组当中的内容显示在同一个界面当中search   按照正则表达式,把第一次匹配到的内容返回出来,返回的是对象能够把匹配到的结果和分组当中的内容显示在同一个界面当中对象.group()  返回的是匹配到的结果对象.groups() 返回的是括号分组里面的内容如果匹配不到内容,返回的是None,无法调用 group() 或者 groups()
"""# 练习3 匹配 www.baidu.com 或者 www.oldboy.com# findall 用法
strvar = "www.baidu.com www.sogou.com www.oldboy.com"
lst = re.findall(r"(?:www).(?:baidu|oldboy).(?:com)",strvar)
print(lst) # ['www.baidu.com', 'www.oldboy.com']# search 用法
strvar = "www.baidu.com www.sogou.com www.oldboy.com"
obj = re.search(r"www\.(baidu|oldboy)\.(com)",strvar)# 返回的是匹配到的结果
res = obj.group()
print(res) # www.baidu.com# 返回的是括号分组里面的内容
res = obj.groups()
print(res) # ('baidu', 'com')# 通过group和下标可以获取到括号里面的内容
print(obj.group(1)) # baidu
print(obj.group(2)) # com# 练习4 "5*6-9/3" 匹配 5*6 或者 9/3 算出最后的结果
strvar = "5*6-7/3"# 匹配5*6
obj = re.search(r"\d+[*/]\d+",strvar)
print(obj) # <_sre.SRE_Match object; span=(0, 3), match='5*6'>
strvar1 = obj.group()
print(strvar1,type(strvar1)) # 5*6 <class 'str'># 计算5*6
num1,num2 = strvar1.split("*")
print(num1,num2) # 5 6
strvar2 = str(int(num1) * int(num2))
print(strvar2,type(strvar2)) # 30 <class 'str'># 替换5*6为字符串30
strvar3 = strvar.replace(strvar1,strvar2)
print(strvar3,type(strvar3)) # 30-9/3 <class 'str'># 匹配9/3
obj = re.search(r"\d+[*/]\d+",strvar3)
print(obj)
strvar4 = obj.group()
print(strvar4) # 9/3# 计算9/3
num1,num2 = strvar4.split("/")
strvar5 = str(int(num1) / int(num2))
print(strvar5)# 替换9/3为字符串3
strvar6 = strvar3.replace(strvar4,strvar5)
print(strvar6)# 计算 30-3 得出最后结果
num1,num2 = strvar6.split("-")
res = float(num1) - float(num2)
print(res)

\num 反向引用

strvar = "<avi>今天是个好日子~</avi>"
lst = re.findall(r"<(.*?)>(.*?)<(.*?)>",strvar)
print(lst) # [('avi', '今天是个好日子~', '/avi')]# 反向引用: 把匹配到的值,再引用一次 (\1 把第一个括号分组里面的内容,拿出来再匹配一下)
lst = re.findall(r"<(.*?)>(.*?)<(/\1)>",strvar)
print(lst) # [('avi', '今天是个好日子~', '/avi')]# \1 代表反向引用第一个括号分组内容 \2 代表反向引用第二个括号分组内容
strvar = "a1b2cab"
obj = re.search(r"(.*?)\d(.*?)\d(.*?)\1\2",strvar)
print(obj)
# 获取匹配到的内容
res1 = obj.group()
print(res1) # a1b2cab
# 获取分组里面的内容
res2 = obj.groups()
print(res2) # ('a', 'b', 'c')

命名分组

命名分组

  1. (?P<组名>正则表达式) 给这个组起一个名字
  2. (?P=组名) 引用之前组的名字 , 把该组名匹配到的内容放到当前位置
# 方法一
strvar = "f6g7hfg"
obj = re.search(r"(?P<tag1>.*?)\d(?P<tag2>.*?)\d(?P<tag3>.*?)\1\2",strvar)
# 获取匹配到的内容
res1 = obj.group()
print(res1) # f6g7hfg
# 获取分组里面的内容
res2 = obj.groups()
print(res2) # ('f', 'g', 'h')# 方法二
strvar = "f6g7hfg"
obj = re.search(r"(?P<tag1>.*?)\d(?P<tag2>.*?)\d(?P<tag3>.*?)(?P=tag1)(?P=tag2)",strvar)
# 获取匹配到的内容
res1 = obj.group()
print(res1)
# 获取分组里面的内容
res2 = obj.groups()
print(res2)

python-正则表达式-单字符匹配_多字符匹配_匹配分组_命名分组相关推荐

  1. python 正则表达式 断言 不定长表达式_【教程】详解Python正则表达式之: (?!…) negative lookahead assertion 前向否定匹配 /前向否定断言...

    Python 2.7的官网文档中的解释是:(?!...)Matches if ... doesn't match next. This is a negative lookahead assertio ...

  2. 详解Python正则表达式之: (?Pname…) named group 带命名的组

    2019独角兽企业重金招聘Python工程师标准>>> Python 2.7的手册中的解释: (?P<name>...) Similar to regular paren ...

  3. python正则表达式--分组、后向引用、前(后)向断言

    无名.有名分组 (1)正则表达式-无名分组 从正则表 达式的左边开始看,看到的第一个左括号"("表示表示第一个分组,第二个表示第二个分组, 依次类推. 需要注意的是,有一个隐含的全 ...

  4. Python 正则表达式(分组)

    正则表达式分组 分组就是用一对圆括号"()"括起来的正则表达式,匹配出的内容就表示一个分组.从正则表达式的左边开始看,看到的第一个左括号"("表示第一个分组,第 ...

  5. python正则表达式开头和结尾_Python 基础之正则之一 单字符,多字符匹配及开头结尾匹配...

    一.正则表达式之单个字符匹配 格式:lst = re.findall(正则表达式,要匹配的字符串) 预定义字符集 匹配内容 .匹配任意字符,除了换行符\n \d匹配数字 \D匹配非数字 \w匹配字母或 ...

  6. python 如何匹配一撇字符_使用Python正则表达式解析斜杠和撇号

    我试图用Python正则表达式库解析维基百科SQL转储.最终目标是将此转储导入PostgreSQL,但我知道字符串中的撇号需要事先加倍. 尽管在这个转储中的字符串中的每个撇号都有一个反斜杠,我宁愿不删 ...

  7. 【Java 正则表达式】单字符匹配、预定字符、量词、Matcher(贪婪、勉强、独占模式)、捕获组、边界匹配符、String类与正则表达式

    正则表达式(Regex Expression) 字符串的合法验证 自己编写验证逻辑 使用正则表达式 单字符匹配 预定义字符 量词(Quantifier) Pattern.Matcher Matcher ...

  8. 三十二、(重点)正则表达式1:re模块(re.match、group())、正则表达式单字符匹配、正则数量({m}、{m,n})

    一.re模块(re.match.group()方法) 1. 2.re.match() 能够匹配出以xxx开头的字符串(从左到右开始依次匹配) 3.若匹配成功,返回字符串的匹配成功的部分,同时可以使用g ...

  9. Python中正则表达式对单个字符,多个字符,匹配边界等使用

    Regular Expression,正则表达式,又称正规表示式.正规表示法.正则表达式.规则表达式.常规表示法(英语:Regular Expression,在代码中常简写为regex.regexp或 ...

最新文章

  1. 理解神经网络,从简单的例子开始(1)7行python代码构建神经网络
  2. Kaggle八项大奖斩获其6:用于筛选和分析文献的paperai
  3. 数据中心ECC值班长岗位提升工作总结
  4. JavaWeb中的乱码解决方法总结
  5. Sum of Even Numbers After Queries
  6. 网页获取客户端IP的两种方法
  7. oracle之set运算符和练习
  8. html5边框闪烁,HTML – CSS框阴影动画像素艺术闪烁
  9. Angular 垮台、ES6 最受欢迎,20,000 名程序员告诉你谁是 JS 王者!
  10. Ubuntu 搭建 NVIDIA驱动 CUDA 和 pytorch GPU 环境
  11. 文本文件中,如何判断有效换行?
  12. XLSTransformer+模板 导出 Excel
  13. JAVA 生成随机数两种方式
  14. 单片机 舵机 SG90 舵机 控制原理 MSP432 单片机
  15. JAVA 经纬度转换成直角坐标系,以及直角坐标系转换成经纬度算法
  16. java类成员变量初始化_Java类变量和成员变量初始化过程
  17. 物联网技术练习题(一)——单选题与判断题
  18. GBA火焰纹章改版-智慧的结晶
  19. 国培_阶段性学习总结
  20. Centos 6、7 配置BBR加速

热门文章

  1. 微店和微商城,你还傻傻分不清?
  2. 【研究生学术英语读写教程翻译 中国科学院大学Unit9】
  3. amd超频软件LINUX,amd锐龙超频软件2020下载
  4. 超声波测距模块(1602LCD显示)—基于51单片机
  5. 【HNU小学期硬件实训】基于QT上位机的汽车监控警报系统
  6. 最年轻图灵奖得主:计算机是数学好的女性的完美学科
  7. 荣耀畅玩5a android5.0,华为荣耀畅玩5A官方固件rom包_荣耀畅玩5A刷机包_升级包
  8. ping直连同网段设备的过程
  9. 手把手带你刷好题(牛客刷题⑤)
  10. 根目录扩容(红帽系列,版本1)