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. [C++] 对象指针使用方法

    对象指针:指向类对象的指针 类指针指向类变量(对象)的地址 对象指针定义格式: 类类型 *变量名: 举例: #include <iostream> using namespace std; ...

  2. Mac php 装imagick扩展 菜鸟教程

    1.2.直接brew install imagemagick@6完成安装 2.去http://pecl.php.net/package/imagick下载安装包 2.1.下载完后解压tar -xzvf ...

  3. 【转】使用eclipse的todo标签管理任务

    Eclipse中的一些特殊的注释技术包括:    1.    // TODO —— 表示尚未完成的待办事项.    2.    // XXX —— 表示被注释的代码虽然实现了功能,但是实现方案有待商榷 ...

  4. js实现字符串切割并转换成对象格式保存到本地

    // split() 将字符串按照指定的规则分割成字符串数组,并返回此数组(字符串转数组的方法) //分割字符串 var bStr = "www.baidu.con"; var a ...

  5. 《精通CSS第3版》(3)可见格式化模型+(4)网页排版

  6. Java JDBC利用反射技术将查询结果封装为对象

    1.JDBC将返回结果集封装成对象demo class JdbcDemo { /** * 获取数据库列名 * @param rs * @return */ private static String[ ...

  7. elasticsearch jestclient api

    1.es search sroll 可以遍历索引下所有数据 public class TestDemo { @Test public void searchSroll() { JestClientFa ...

  8. WebGL学习笔记(七):输入和动画

    目前为止,我们绘制出来的3D物体都是静止的,接下来我们需要让桌面上的小盒子可以根据我们按键(上下键)前进后退: 输入方面,监听按键和鼠标消息直接在document上添加对应的监听就行了: 动画这块,我 ...

  9. saltstack执行state.sls耗时长的坑

    一直用的 jenkins + saltstack 自动化构建发布项目,一共也就不超过20台服务器,奈何运行时间越来越慢,并且负载越来越高(这里大部分都是使用state模块),但是不用state模块效率 ...

  10. 解决端口被占用问题(端口timewait)

    当jmeter做千级并发时,有报错的接口,查看是不是本地端口被占用完了 netstat -an   查看是否有端口在 timewait timewait是知道用那个端口,但是端口被别人占用着 见tcp ...