python day 6

2019/10/09

学习资料来自老男孩教育

1. 装饰器decorator

一旦挂上装饰器,函数就会变成装饰器的inner函数。

1.1. 接收任意个参数的装饰器。

def outter(func):
def inner(*args,**kwargs):
print(123)
ret = func(*args,**kwargs)
print(456)
return ret
return inner @outter
def hello(name):
print('hello %s' % name)
hello('lanxing')

1.2. 多个装饰器装饰同一个参数

def outter1(func):
def inner(*args,**kwargs):
print(123)
ret = func(*args,**kwargs)
print(456)
return ret
return inner def outter2(func):
def inner(*args,**kwargs):
print(123)
ret = func(*args,**kwargs)
print(456)
return ret
return inner @outter1
@outter2
def hello(name):
print('hello %s' % name) hello('lanxing')

2. 正则表达式re

2.1 正则表达式概述

在开发中会有大量的字符串处理工作,其中经常会涉及到字符串格式的校验

例如:如何判断一个字符串是不是手机号(检测用户填写)

17611105750

11位;数字组成不能包含其他字符;1开头;第二位是3,4,5,7,8

如何将以上规则描述出来,让计算机可以识别,就是正则表达式要完成的工作。

正则表达式是一个特殊的字符序列:用来描述某个规则

正则表达式的大致匹配过程是:依次拿出表达式(规则)和文本中的字符比较,如果每一个字符都能匹配,则匹配成功;一旦有匹配不成功的字符则匹配失败。

它能帮助你方便的检查一个字符串是否与某种模式匹配,也叫正规表示法、规则表达式、常规表示法。。。等等。常简写为RE。

英语:Regular Expression 这里的regular指‘规则’

Regular Expression 即 “描述某种规则的表达式”

正则表达式并不是Python的一部分

正则表达式是用于处理字符串的工具,拥有自己独特的语法以及一个独立的处理引擎,在提供了正则表达式的语言里,正则表达式的语法都是一样的。

(不同的编程语言支持的语法数量不同)

Python中需要通过正则表达式对字符串进⾏匹配的时候, 使⽤re模块。

re 模块是Python当中提供的正则表达式工具包,使Python语言拥有全部的正则表达式功能

2.2 re模块常用方法

  • match(匹配)

使用match方法进行匹配操作:

re.match 尝试从字符串的起始位置匹配一个模式

re.match(正则表达式,要匹配的字符串):

  1. match方法的第一个参数接收的是描述某个规则的字符串.
  2. 第二个参数是要进行校验的值.
  3. 从左向右开始匹配.

re.match()是用来进行匹配检查的方法,若正则表达式与字符串规则匹配,则返回匹配对象(Match Object),否则返回None.

匹配对象Match Object具有一个group方法,用来返回字符串中匹配的部分.

(如果匹配到数据的话, 可以使⽤group⽅法来提取匹配到的数据).

import re
line = 'qwertyuiop' #不具备通用性
s = "qwertyuiopl"
print(re.match(line, s).group()) import re
line = 'Hello 123 4567 World_This is a Regex Demo'
result = re.match('Hello\s\d\d\d\s\d{4}\s\w{10}', line)
print(result)
print(result.group())
  • 表示字符
字符 功能 备注
. 点号表示匹配任意一个字符
[] 匹配中括号[]里面的一个字符
\d 表示0-9之间的数字,包括0与9 相当于[0-9]
\D 表示除了0-9的字符,即\d的取反 相当于[^0-9]
\w 匹配单词字符,即0-9,a-z,A-Z以及下划线_ 相当于[0-9a-zA-Z_]
\W 匹配非单词字符 相当于[^0-9a-zA-Z_]
\s 匹配空白符,即空格键,tab键\t,换行\n
\S 匹配非空白符

正则表达式⾥使⽤“\”作为转义字符(\d)。

由于正则表达式使用反斜杠来转义特殊字符,而python自身处理字符串时,反斜杠也是用于转义字符,这样就产生了一个双重转换的问题

假如你需要匹配⽂本中的字符"", 那么使⽤正则表达式⾥将需要4个反斜杠"\": 前两个和后两个分别⽤于在编程语⾔⾥转义成反斜杠, 转换成两个反斜杠后再在正则表达式⾥转义成⼀个反斜杠。

Python中字符串前⾯加上 r 表示原⽣字符串(真实字符串)

原⽣字符串很好地解决了上面的这个问题, 有了原始字符串, 你再也不⽤担⼼是不是漏写了反斜杠。

'r'是防止字符转义的 如果路径中出现'\t'的话 不加r的话\t就会被转义 而加了'r'之后'\t'就能保留原有的样子。

所以以后凡是使用正则表达式,就先加上r。

ret = re.match(r"c:\\a", "c:\\a\\b\\c" )

ret.group()

从字符串输入到代码转义一次,又在生成正则表达式的时候再转义一次,于是就需要多打反斜杠。用r""可以抵消掉第一次转义.

r只抵消第一次转义:python正则表达式加了r之后\w,\s,.这些有含义的字符仍然有效.

  • 表示数量
字符 功能
* 匹配前一个字符0次或多次,即可有可无,\d*表示匹配0个或多个数字
+ 匹配前一个字符1次或多次,即至少一次
? 匹配前一个字符1次或0次,即要么有1次,或者0次
{m} 匹配前一个字符m次
{m,} 匹配前一个字符至少m次或无限次
{m,n} 匹配前一个字符从m次到n次,可以替代*+?
  • 表示边界
字符 功能
^ 匹配字符串开头,(必须以某个条件开头)
$ 匹配字符串结尾
\b 匹配单词边界,需要加r
\B 匹配非单词边界
print(re.match('^The', 'The end').group())
匹配以The开头的字符串 print(re.match('\w*\send$', 'The end').group())
匹配必须以end结尾
print(re.match(‘\w*\send$’, ‘The endd’).group()) #出错 `re.match(r".*\bver\b", "ho ver abc").group()`
`re.match(r".*\bver\b", "ho verabc").group()`
`re.match(r".*\bver\b", "hover abc").group()`
\b匹配的位置:前面和后面的字符不全是\w匹配成功,反过来理解,如果\b的前面和后面都是\w,则不匹配 匹配大陆手机号
re.match("^1[34578]\d{9}$", "17611105750")
  • 匹配分组
字符 功能
| 匹配左右任意一个表达式(左或右)
(ab) 将括号中字符作为一个分组
\num 引用分组num匹配到的字符串
(?P<name>) 分组起别名
(?P=name) 引用别名为name分组匹配到的字符串
# 匹配1-100之间的数字:
ret = re.match(‘[1-9]\d?$|0$|100$',“8")
print(ret.group()) ret = re.match('[1-9]?\d$|100$','8')

分组就是用一对圆括号“()”括起来的正则表达式,匹配出的内容就表示一个分组。

从正则表达式的左边开始看,看到的第一个左括号“(”表示第一个分组,第二个表示第二个分组,依次类推,需要注意的是,有一个隐含的全局分组(0),就是整个正则表达式。

分完组以后,要想获得某个分组的内容,直接使用group(num)和groups()函数提取

ret = re.match("\w{4,20}@163\.com", "test@163.com")
ret = re.match("\w{4,20}@(163|126|qq)\.com", "test@126.com")
ret = re.match("\w{4,20}@(163|126|qq)\.com", "test@qq.com")
ret = re.match("([^-]*)-(\d+)","010-12345678")
ret.group()
#'010-12345678'
ret.group(1)
#'010'
ret.group(2)
#'12345678'
ret.groups() ret = re.match(r"<(\w*)><(\w*)>.*</\2></\1>", "<html><h1>www.sxt.cn</h1></html>")
ret.group() ret = re.match(r"<(\w*)><(\w*)>.*</\2></\1>", "<html><h1>www.sxt.cn</h2></html>")
ret.group() ret = re.match(r"<(?P<name1>\w*)><(?P<name2>\w*)>.*</(?P=name2)></(?P=name1)>", "<html><h1>www.sxt.cn</h1></html>")
ret.group() ret = re.match(r"<(?P<name1>\w*)><(?P<name2>\w*)>.*</(?P=name2)></(?P=name1)>", "<html><h1>www.sxt.cn</h2></html>")
ret.group()
# 注意: (?P<name>) 和 (?P=name) 中的字⺟p⼤写
  • re模块的其他函数
  1. match: re.match(pattern,string,flags=0),从头开始匹配,匹配成功返回一个匹配对象,该匹配对象有group,start,end,span,groups等方法,用于返回匹配内容,匹配不成功则返回None,不成功时,没有group方法。flags是编译标志位,用于修改正则表达式的匹配方式,如:是否匹配大小写,是否多行匹配等。

    flags的实参有以下几种:

    1.1. re.I 使匹配对大小写不敏感。

    1.2. re.L 做本地化识别(locale-aware)匹配.

    1.3. re.M 多行匹配,影响^和$.

    1.4. re.S 使.匹配包括换行在内的所有字符

    1.5. re.U 根据Unicode字符集解析字符,影响\w,\W,\b,\B

    1.6. re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更灵活。

    匹配成功返回的对象的方法有以下几种:

    1.7. group(n=0) 不传参数,默认是0,返回re整体匹配的字符串,可以一次输入多个组号,对应组的组号。

    1.8. group(n,m) 返回组号为n,m所匹配的字符串,如果组号不存在,会报错。

    1.9. groups() 返回一个元组,元组中元素是正则表达式中每个小组匹配到的字符串。通常groups不加参数。

    1.10. start() 返回匹配开始的位置。

    1.11. end() 返回匹配结束的位置。

    1.12. span() 返回一个元组包含匹配(开始,结束)的位置。

    re.match('com','comww.runcomoob').group()

    re.match('com','Comww.runcomoob',re.I).group()
  2. search re.search(pattern,string,flags=0)搜索符合特征的第一个字符串,匹配成功返回一个匹配对象,该匹配对象有group,start,end,span,groups等方法,用于返回匹配内容,匹配不成功则返回None,不成功时,没有group方法:

    ret = re.search(r"\d+", "阅读次数为 9999")

    ret.group()
  3. findall 找出所有符合特征的字符串,并返回一个列表,不需要用group方法即可返回列表,finall优先返回组里面的内容,如果要取消,则在组前面加上?:;如果pattern有超过1个分组,则列表的元素是一个包含所有分组匹配内容的元组:

    In [32]: re.findall(r'(\d{0,4})','xyz024abc123')

    Out[32]: ['', '', '', '024', '', '', '', '123', '']

    In [33]: re.findall(r'(\d{0,4})(\w{0,3})(\d)','xyz024abc123')

    Out[33]: [('', 'xyz', '0'), ('24', 'abc', '1'), ('2', '', '3')]
  4. sub re.sub(pattern,repl,string,max=0)将匹配到的数据进⾏替换,返回替换后的字符串,max指最大替换多少次,默认0是全部替换。:

    ret = re.sub(r"\d+", '998', "python = 997")

    ret = re.sub(r'g.t','have','I get apple, I got orange, I gut banana.',2)
  5. split:re.split(pattern,string),根据匹配进⾏切割字符串,并返回⼀个列表:

    ret = re.split(r":| ","info:xiaoZhang 33 shandong")

    p = re.compile('\d')

    In [38]: p.split('one1two2three3four4')

    Out[38]: ['one', 'two', 'three', 'four', '']
  6. compile: re.compile(strPattern[,flag]) 如果要多次调用规则,则使用compile方法,先将规则编译好。

    regex = re.compile(r'\w*oo\w*'),regex.findall('helloo, good')
  7. finditer(pattern,string),返回的是包含匹配对象的迭代器。如果要获得匹配内容,得遍历迭代器得到匹配对象,再调用匹配对象的group方法。

    re.finditer(r'\d+','12drum44ers druming,11,drun12,13,14')
  • 贪婪和非贪婪

Python⾥正则表达式数量词( "*","?","+","{m,n}" )默认是贪婪的, 总是尝试匹配尽可能多的字符

s = "number is 123456789"
ret = re.match(r"(.+)(\d)",s)
print(ret.group(1))

⾮贪婪则相反, 总是尝试匹配尽可能少的字符:

在"*","?","+","{m,n}"后⾯加上? , 使贪婪变成⾮贪婪.

result = re.match(r"aa(\d+)","aa2343ddd").group(1)

'2343'

result = re.match(r"aa(\d+?)","aa2343ddd").group(1)

'2'

贪婪和非贪婪的到的结果也有可能是一样的

result = re.match(r"aa(\d+)ddd","aa2343ddd").group(1)

'2343'

result = re.match(r"aa(\d+?)ddd","aa2343ddd").group(1)

'2343'

作业:

import re
# 1. 判断字符串是否是全部小写
s1 = 'qwerty123A'
result1 = re.match('^[a-z]*$',s1)
if result1:
print(result1.group())
else:
print('不是全部小写,无法匹配') # 2. 匹配由数字/26个英文字母组成的字符串
p2= '[0-9a-zA-Z]*'
s2 ='1323abcABC_xyz'
result2 = re.match(p2,s2)
print(result2.group()) # 3. 匹配长度为8-10的用户密码(以字母开头/数字/下划线)
p3 = '^[a-zA-Z]\w{7,9}$'
s3 = 'abc1323_xy'
result3 = re.match(p3,s3)
print(result3.group()) # 4. 电子邮箱验证
p4 = r'\w{4,20}@(163|126|qq)\.com'
s4 = '3768094lan@163.com'
result4 = re.match(p4,s4)
if result4:
print(result4.group()) # 5. 简单的身份证号验证
p5 = r'[1-6]\d{5}(18|19|20)\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d$|X$)'
s5 = '36078219880631032X' result5 = re.match(p5,s5)
if result5:
print(result5.group())
else:
print('不是身份证号码') # 6. 提取并捕获html标签内容
p6 = r'<(?P<html>\w*)><(?P<h1>\w*)>(.*)</(?P=h1)></(?P=html)>'
s6 = '<html><h1>我爱你</h1></html>'
result6 = re.match(p6,s6)
if result6:
print(result6.group(3))
else:
print('不正确')

python day6 装饰器补充,正则表达式的更多相关文章

  1. Python札记 -- 装饰器补充

    本随笔是对Python札记 -- 装饰器的一些补充. 使用装饰器的时候,被装饰函数的一些属性会丢失,比如如下代码: #!/usr/bin/env python def deco(func): def ...

  2. python之装饰器补充与递归函数与二分查找

    目录 多层装饰器 有参装饰器 递归函数 基本演示 斐波那契数列 总结 小拓展 算法之二分法 简介 举例 总结 多层装饰器 我们已经知道了语法糖的作用是将装饰对象自动装饰到装饰器中,一个语法糖的应用我们 ...

  3. 【转】详解Python的装饰器

    原文链接:http://python.jobbole.com/86717/ Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现 ...

  4. 详解Python的装饰器

    Python中的装饰器是你进入Python大门的一道坎,不管你跨不跨过去它都在那里. 为什么需要装饰器 我们假设你的程序实现了say_hello()和say_goodbye()两个函数. def sa ...

  5. Python的装饰器实例用法小结

    这篇文章主要介绍了Python装饰器用法,结合实例形式总结分析了Python常用装饰器的概念.功能.使用方法及相关注意事项 一.装饰器是什么 python的装饰器本质上是一个Python函数,它可以让 ...

  6. 第五章 Python之装饰器

    函数对象 函数是第一类对象:即函数可以当作数据传递 #可以被引用,可以被当作参数传递,返回值可以是函数,可以当作容器类型的元素 #引用 def func(x,y): print(x,y) f=func ...

  7. 我终于弄懂了Python的装饰器(四)

    此系列文档: 1. 我终于弄懂了Python的装饰器(一) 2. 我终于弄懂了Python的装饰器(二) 3. 我终于弄懂了Python的装饰器(三) 4. 我终于弄懂了Python的装饰器(四) 四 ...

  8. Python各式装饰器

    Python装饰器,分两部分,一是装饰器本身的定义,一是被装饰器对象的定义. 一.函数式装饰器:装饰器本身是一个函数. 1.装饰函数:被装饰对象是一个函数 [1]装饰器无参数: a.被装饰对象无参数: ...

  9. python基础——装饰器

    python基础——装饰器 由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数. >>> def now(): ... print('2015-3-25 ...

随机推荐

  1. linux core 性能

    apt-get install lrzsz apt-get install vim apt-get install -y net-tools apt-get install -y procps htt ...

  2. phpstudy apache 服务无法启动

    1.找到apache路径 3.打开cmd进入bin文件夹 4.输入 httpd.exe  看报的什么错误即可解决 我的这边是httpd.config 里面配置了个项目文件夹路径,这个文件夹被我删了,导 ...

  3. Springboot属性加载与覆盖优先级与SpringCloud Config Service配置

    参考官方文档:https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config. ...

  4. (8)Flask微电影项目会员中心其他页面搭建

    会员中心修改密码.评论.登录日志和收藏电影4个页面的内容. 一.修改密码页面: {% extends "home/home.html" %} {% block css %} < ...

  5. Axure中继器设置单选

    我们给元件添加组的名称是为了让软件知道哪些元件被放进了一个组中,然后软件会自动让这个组中只有一个元件能够是选中状态,以达到唯一被选中的效果.而中继器的这两个属性默认是启用的状态, 会把组的效果给取消, ...

  6. 复制pycharm虚拟环境

    我还是在内网进行开发,上篇讲了数据库驱动,方便链接数据库. 那么虚拟环境呢?那么多个包,离线下载………… 关键是我自己的笔记本也会进行交叉开发.一会儿在内网,一会儿在公网. 还是复制粘贴比较简单. 下 ...

  7. Grafana修改背景色

    grafana默认主题色是黑底白字,我们将它修改成白底黑字: in /etc/grafana/grafana.ini uncomment line and set default_theme = li ...

  8. Jenkins配置发送邮件步骤

    Jenkins配置邮件步骤,以下我是以腾讯企业邮箱账号作为演示 1.配置Jenkins系统管理员邮件地址: 下拉找到以下位置 2.配置邮件通知 继续下拉,找到邮件配置.输入SMTp服务器以及邮箱后缀, ...

  9. [LeetCode] 639. Decode Ways II 解码方法 II

    A message containing letters from A-Z is being encoded to numbers using the following mapping way: ' ...

  10. MySQL之表关系

    MySQL表关系 一对多关系 一对多与多对一是一个概念,指的是一个实体的某个数据与另外一个实体的多个数据有关联关系. 举例,学校中一个学.院可以有很多的学生,而一个学生只属于某一个学院(通常情况下), ...