python day15

今日内容


 

昨日内容补充:


 

对于两个文件中的互相导入md模块问题分析:

x = 1from md import xprint(x)# md中的xfrom md import xx = 1000print(x)# 当前文件中的x

__all__ 列表写什么,执行导入语句那个文件就能拿到什么;

__all__不写的情况,默认是将所在文件所有的名字都暴露给导入者.

解决循环导入的第三种方式(前两种已在day14涉及):

  • 将循环导入的名字,放到另外一个文件中

 

正则表达式


定义: 正则就是用来筛选字符串中的特定的内容的,对字符串进行操作的逻辑工具

re模块与正则表达式之间的关系:

  • 正则表达式不是python独有的,它是一门独立技术
  • 所有的编程语言都可以用正则
  • 如果想在python中用,就必须依赖于re模块

相关书籍: <正则指引>

验证工具: www.tool.chinaz.com

正则的应用场景:

  • 1.爬虫
  • 2.数据分析

 注意点: 只要是reg...一般情况下都是跟正则有关,而且如果想匹配具体的内容,可以直接写完整的内容,不需要写正则

 

字符组[ ]:

正则
待匹配字符
 
 匹配结果
说明
 
[0123456789]
 8 
True
在一个字符组里枚举合法的所有字符,字符组里的任意一个字符
和"待匹配字符"相同都视为可以匹配
 
[0123456789]
 a 
False
 
由于字符组中没有"a"字符,所以不能匹配
 
[0-9]
 7 
True
 
也可以用-表示范围,[0-9]就和[0123456789]是一个意思
 
[a-z]
 s 
True
 
同样的如果要匹配所有的小写字母,直接用[a-z]就可以表示
 
[A-Z]
 B 
True
 
[A-Z]就表示所有的大写字母
 
[0-9a-fA-F]
 e 
True
 
可以匹配数字,大小写形式的a~f,用来验证十六进制字符

关于字符:

元字符
匹配内容
.匹配除换行符以外的任意字符
\w匹配字母或数字或下划线
\s匹配任意的空白符
\d匹配数字
\n匹配一个换行符
\t匹配一个制表符
\b匹配一个单词的结尾
^匹配字符串的开始
$匹配字符串的结尾
\W
匹配非字母或数字或下划线
\D
匹配非数字
\S
匹配非空白符
a|b
匹配字符a或字符b
()
匹配括号内的表达式,也表示一个组
[...]
匹配字符组中的字符
[^...]
匹配除了字符组中字符的所有字符

 

关于量词:

量词
用法说明
*重复零次或更多次
+重复一次或更多次
?重复零次或一次
{n}重复n次
{n,}重复n次或更多次
{n,m}重复n到m次


注意点:

  • 通常一个字符组里面的表达式都是或关系
  • \w:\word与\W相反
  • \s:\space与\S相反
  • \d:\digit与\D相反
  • ^匹配字符串的开始 类似于startswith
  • $匹配字符串的结尾 类似于endswith
  • ^如果直接写在外面,就是限制字符串开头的作用
  • [^...]就是取反的意思,除了...之外其他都能输出
  • a|b,如果是abc|ab,一定要将长的放在前面

PS: ^与$连用,就能精准限制匹配的内容,两者之间写什么,匹配的字符串就必须是什么,多一个不行,少一个也不行

例如:^jason$,最终输出结果就一定是jason

贪婪匹配Patten与非贪婪匹配:

正则待匹配字符匹配结果说明
<.*>  <script>...<script><script>...<script>
默认为贪婪匹配模式,会匹配尽量长的字符串
<.*?>r'\d'   <script>
<script>
加上?为将贪婪匹配模式转为非贪婪匹配模式,会匹配尽量短的字符串
  • <.*>:先拿着里面的.*去匹配所有的内容,然后再根据>往回退着找,遇到即停止

  • <.*?>:先拿着?后面的>去匹配符合条件的最少的内容,然后把匹配的结果返回

PS:根据匹配的内部原理可以很好的理解, .*?x 就是取前面任意长度的字符,直到一个x出现

 

注意点:

  • 正则在匹配的时候默认都是贪婪匹配(尽量匹配多的)
  • 量词必须跟在正则符号后面
  • 量词只能够限制紧挨着它的左侧表达式的那一个正则符号
  • 量词后面加上一个?就可以将贪婪匹配变成非贪婪匹配(惰性匹配)

分组()  或|  [^]:

正则待匹配字符匹配结果说明
^[1-9]\d{13,16}[0-9x]$110101198001017032110101198001017032表示可以匹配一个正确的身份证号
^[1-9]\d{13,16}[0-9x]$11010119800101701101011980010170
表示也可以匹配这串数字,但这并不是一个正确的身份证号码,它是一个16位的数字
^[1-9]\d{14}(\d{2}[0-9x])?$1101011980010170False
现在不会匹配错误的身份证号了
()表示分组,将\d{2}[0-9x]分成一组,就可以整体约束他们出现的次数为0-1次
^([1-9]\d{16}[0-9x]|[1-9]\d{14})$110105199812067023110105199812067023
表示先匹配[1-9]\d{16}[0-9x]如果没有匹配上就匹配[1-9]\d{14}

定义:当多个正则符号需要重复多次时,或者当作一个整体进行其他操作,那么可以分组

分组在正则的语法中就是( )

例如: 用[a-z][0-9]会匹配到三个结果,这个时候就可以用分组([a-z][0-9])+,可以提高不少效率

例题: 关于身份证的正则表达式

  • ^[1-9]\d{13,16}[0-9x]$
  • ^[1-9]\d{14}(\d{2}[0-9x])?$
  • ^([1-9]\d{16}[0-9x]|[1-9]\d{14})$

 上面三种都是解决方法,第三种考虑的最全面

转义符:

正则待匹配字符匹配结果说明
 \n \n False
因为在正则表达式中\是有特殊意义的字符,所以要匹配\n本身,用表达式\n无法匹配
\\n \n   True 
转义\之后变成\\,即可匹配
 '\\\\n' '\\n'  True 
如果在python中,字符串中的'\'也需要转义,所以每一个字符串'\'又需要转义一次
 r'\\n' r'\n'  True 
在字符串之前加r,让整个字符串不转义

注意点:

  • 在正则表达式中,有很多有特殊意义的是元字符,比如\n和\s等,如果要在正则中匹配正常的"\n"而不是"换行符"就需要对""进行转义,变成'\'
  • python中,无论是正则表达式,还是待匹配的内容,都是以字符串的形式出现的
  • 字符串中\也有特殊的含义,本身还需要转义
  • 如果匹配一次"\n",字符串中要写成'\\n'
  • 如果匹配一次"\\n",字符串中要写成'\\\\n'
  • r'\\n' 在字符串前面加个r,让整个字符串不转义(了解:r其实就是real的意思,真实不转义)

 

re模块:


 

定义:python中使用正则必须借助于re模块,或者是支持正则表达式书写的功能与方法

 while True:phone_number = input('please input your phone number : ')if len(phone_number) == 11 \and phone_number.isdigit()\and (phone_number.startswith('13') \or phone_number.startswith('14') \or phone_number.startswith('15') \or phone_number.startswith('16') \or phone_number.startswith('17') \or phone_number.startswith('18')):print('是合法的手机号码')else:print('不是合法的手机号码')import rephone_number = input('please input your phone number : ')if re.match('^(13|14|15|16|17|18)[0-9]{9}$',phone_number):print('是合法的手机号码')else:print('不是合法的手机号码')
运用正则表达式+re模块来解决用户以手机号来注册并验证的问题

三种主要方法:

  • findall找出字符串中符合正则表达式的全部内容,并且返回的是一个列表,列表中的元素就是正则匹配到的结果
  • searfch只会依据正则查一次 只要查到了结果,就不会再往后查找;当查找的结果不存在的情况下 调用group直接报错
  • match只会匹配字符串的开头部分;当字符串的开头不符合匹配规则的情况下 返回的也是None 调用group也会报错
ret = re.findall('[a-z]+', 'eva egon jason')# findall('正则表达式', '带匹配的字符串')print(ret)  # ['eva', 'egon', 'jason']
findall
ret = re.search('a', 'eva egon jason')# search('正则表达式', '带匹配的字符串')print(ret)  # 返回 <_sre.SRE_Match object; span=(2, 3), match='a'> # search不会给你直接返回匹配到的结果,而是给你返回一个对象print(ret.group())  # a# 必须调用group才能看到匹配到的结果
search(正常选存在的字符)
ret1 = re.search('k', 'eva egon jason')print(ret1.group())  # 直接报错,因为print(ret)返回None,而且None没有内置group方法
search(选不存在的字符)
ret = re.match('e', 'eva egon jason')print(ret)  # 返回<_sre.SRE_Match object; span=(0, 1), match='e'> print(ret.group())  # e
match(选首位字符)
ret = re.match('a', 'eva egon jason')print(ret)  #  返回Noneprint(ret.group())  # 直接报错
match(选非首位字符)

其他方法:

split:分割

ret = re.split('[ab], 'abcd')  # 先按'a'分割得到' ''bcd',再对' ''bcd'分别按'b'分割print(ret)  # 返回的还是列表[' ', ' ', 'cd']
split

sub:替换,先按照正则表达式查找所有符合该表达式的内容 统一替换成'新的内容' 还可以通过n来控制替换的个数

ret = re.sub('\d', 'H','eva3egon4yuan4',1)  # 将数字替换成'H',参数1表示只替换1个# sub('正则表达式', '新的内容', '待替换的字符串',n)print(ret)  # 返回值为evaHegon4yuan4
sub

subn:替换(返回元祖)

ret = re.subn('\d', 'H', 'eva3egon4yuan4')  # 将数字替换成'H',返回元组(替换的结果,替换了多少次)

ret1 = re.subn('\d', 'H', 'eva3egon4yuan4',1)  # 将数字替换成'H',返回元组(替换的结果,替换了多少次)print(ret)  # 返回的是一个元组 元组的第二个元素代表的是替换的个数
subn

obj:编译(转换功能)

obj = re.compile('\d{3}')  # 将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字

ret = obj.search('abc123eeee')  # 正则表达式对象调用search,参数为待匹配的字符串

ret1 = obj.findall('347982734729349827384')print(ret.group())  # 返回结果是 123print(ret1)  # 返回结果是 ['347', '982', '734', '729', '349', '827', '384'] 
obj

finditer:返回一个存放匹配结果的迭代器

ret = re.finditer('\d', 'ds3sy4784a')  # finditer返回一个存放匹配结果的迭代器print(ret)  # 返回<callable_iterator object at 内存地址>print(next(ret).group())  # 等价于ret.__next__(),超出迭代取值的范围 直接报错StopIterationprint([i.group() for i in ret])  # 查看剩余的左右结果
finditer

 

扩展知识点:


 

1.?P可以给某一个正则表达式起别名

import reres = re.search('^[1-9] (\d{14})(\d{2}[0-9x])?$','110105199812067023')res = re.search('^[1-9] (?P<password>\d{14})(?P<username>\d{2}[0-9x])?$','110105199812067023')print(res.group())  # 返回值为110105199812067023print(res.group('password'))  # 返回值为110105199812067print(res.group(1))  # 返回值为110105199812067print(res.group('username'))  # 返回值为023print(res.group(2))  # 返回值为023

2.?:取消权限,findall就不会优先把匹配结果组里内容返回

ret1 = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')ret2 = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com') # 忽略分组优先的机制print(ret1,ret2)  # ['oldboy']

3.关于split的知识点

ret=re.split("\d+","eva3egon4yuan")print(ret)  # 结果 : ['eva', 'egon', 'yuan']

ret1=re.split("(\d+)","eva3egon4yuan")print(ret1)  # 结果 : ['eva', '3', 'egon', '4', 'yuan']

 

转载于:https://www.cnblogs.com/zhukaijian/p/11203705.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/461866.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何有效抓取SQL Server的BLOCKING信息

2019独角兽企业重金招聘Python工程师标准>>> SQL Server允许并发操作&#xff0c;BLOCKING是指在某一操作没有完成之前&#xff0c;其他操作必须等待&#xff0c;以便于保证数据的完整性。BLOCKING的解决方法要查看BLOCKING的头是什么&#xff0c;为什么BLOCKING头上…

iOS开发篇——OC 协议和代理设计模式介绍

蓝鸥iOS培训讲师推荐&#xff1a;好久没和大家沟通了&#xff0c;没和大家沟通了&#xff0c;今天就和大家说说有关OC内容协议和代理设计模式。首先要讲的是协议一、协议OC中的协议和接口有些相似&#xff0c;协议中定义的方法&#xff0c;在类中实现。协议一般情况下是用来实现…

uboot的移植——移植uboot官方的uboot到x210开发板

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 参考内容 uboot——官网下载直接移植(一) - biaohc - 博客园 uboot——官网下载直接移植(二) - biaohc - 博客园 uboot移植&#xff08;一&#xff09;配置过程分析_LouisGou的博客-CSDN博客 获取…

[转载]使用Vitamio打造自己的Android万能播放器(7)——在线播放(下载视频)...

前言 本章将实现非常实用的功能——下载在线视频。涉及到多线程、线程更新UI等技术&#xff0c;还需思考产品的设计&#xff0c;如何将新加的功能更好的融入到现有的产品中&#xff0c;并不是简单的加一个界面就行了&#xff0c;欢迎大家交流产品设计和技术细节实现&#xff01…

Hibernate上路_16-继承关系映射

2019独角兽企业重金招聘Python工程师标准>>> 例&#xff1a;员工Employee分为正式工SalaryEmployee和临时工HourEmployee。子类表的字段都不能使用非空约束。 1.三种继承关系的建表方式&#xff1a; 1&#xff09;父类、子类在同一张表&#xff0c;表中有“辨别者…

C++起航篇——bool类型,输入输出,命名空间

以下内容源于慕课网http://www.imooc.com/course/list?ccplusplus的学习整理&#xff0c;如有侵权&#xff0c;请告知删除。 慕课网学习内容 一、起航 二、离航 三、远征 封装继承多态模板 1、c的新特征 &#xff08;1&#xff09;新数据类型 bool &#xff08;true和fals…

C++离航篇——引用,const

以下内容源于http://www.imooc.com/learn/381的学习整理&#xff0c;如有侵权&#xff0c;请告知删除。 一、引用 &#xff08;1&#xff09;引用即定义别名 对引用进行操作即对本身操作&#xff1b;int a10; int &ba; //定义了a的别名b&#xff1b;注意别名是不包括&…

【广搜】棋盘游戏

题目描述 在一个4*4的棋盘上有8个黑棋和8个白棋&#xff0c;当且仅当两个格子有公共边&#xff0c;这两个格子上的棋是相邻的。移动棋子的规则是交换相邻两个棋子。现在给出一个初始棋盘和一个最终棋盘&#xff0c;要求你找出一个最短的移动序列使初始棋盘变为最终棋盘。Klux说…

C++离航篇——函数默认参数、函数重载、内敛函数

1、函数的默认参数 2、函数的重载 &#xff08;1&#xff09;在相同的作用域内&#xff0c;用同一个函数名定义的多个函数&#xff0c;其中每个函数的参数个数、参数类型不同。 3、内联函数 &#xff08;1&#xff09;编译的时候&#xff0c;将函数体代码和相应的实参直接在函…

C++离航篇——内存的申请释放

1、内存的申请和释放 使用关键字new&#xff0c;紧接申请的类型&#xff0c;以及用中括号标明申请多大的内存空间。 2、内存的初始化 注意和块内存申请不同&#xff0c;初始化是&#xff08;&#xff09;&#xff0c;块内存是[ ]。

C++远征之封装篇——类和封装、实例化和对象成员访问

一、封装篇的学习内容数据成员 成员函数构造函数 析构函数对象复制 对象赋值对象数组 对象指针this指针二、类与封装三、实例化和对象成员访问&#xff08;1&#xff09;从栈中实例化对象&#xff08;2&#xff09;从堆中实例化对象 &#xff08;3&#xff09;对象成员的访…

C++远征之封装篇——字符串类型

一、c中的字符串操作函数 二、字符串类型string 1、c中没有字符串类型&#xff0c;只有字符类型 因此对于字符串的操作&#xff0c;一般是用上面的函数来操作。 2、字符串的初始化 3、字符串相关的操作

C++远航之封装篇——数据的封装

以对象为中心&#xff0c;具体来说&#xff0c;以谁做什么来代表程序的逻辑。所有操作都通过调用自己的函数来完成。 数据成员暴露了&#xff0c;不好的设计&#xff1a; 数据的封装&#xff1a;

游戏大厅 从基础开始(7)--绕回来细说聊天室(中间偏下)之女仆编年史2

老少爷们儿反击战 上一篇中 我们的女仆终于可以做一些像阳光下其他人一样的事情了&#xff0c;少爷们可以和女仆酱一起参加下午茶~ 难得的上流社会啊 这是永远1v1被人私有的女奴 和 喝茶时被人共有的女仆酱最明显的差异~ 明媚的午后阳光下&#xff0c;庭院里白色长餐桌两旁&am…

【转载】App.config/Web.config 中特殊字符的处理

写一个网站&#xff0c;遇到一个问题&#xff0c;发布以后&#xff0c;提示错误&#xff0c;但是即使打开错误提示&#xff08;在web.config中打开&#xff09;&#xff0c;还是只提示错误&#xff0c;没提示什么地方错误&#xff0c;这让我知道了&#xff1a;是webconfig本身的…

C++远航之封装篇——类外定义和::

1、类内定义是把函数的具体实现写在类内部&#xff0c;默认是inline函数。 2、类外定义包含两种情况&#xff1a; &#xff08;1&#xff09;同文件类外定义 &#xff08;2&#xff09;不同文件类外定义

pipeline代码自动生成

如图所示&#xff0c;安装完插件后&#xff0c;Sample Step里就有相应的选项&#xff0c;选择某个选项后&#xff0c;点击Generate Pipeline Script按钮&#xff0c;就可以自动生成代码片段&#xff0c;然后放入pipeline流水线里就可以了 pipeline使用的是groovy脚本&#xff0…

一个简单的基于socket的通讯处理程序

2019独角兽企业重金招聘Python工程师标准>>> 这几天看书看得java网络编程&#xff0c;看到一个不错的&#xff0c;适合新手的&#xff0c;部分代码借鉴书上的&#xff0c;可能有地方还不是很成熟&#xff0c;不过可以借鉴一下&#xff0c;分为客户端和服务端&#x…

C++远航之封装篇——构造函数

1、为什么需要构造函数&#xff1f; 见博客http://blog.csdn.net/zhhymh/article/details/6236317 2、c中的内存分区 &#xff08;1&#xff09;栈区 int x0&#xff1b;int *pNULL&#xff1b; &#xff08;2&#xff09;堆区 int *p new int[20]; &#xff08;3&#xff0…

安装win_server_2012的方法

1、从微软官网下载评估版。 2、查看你的当前版本。以管理员身份运行cmd&#xff0c;然后输入“DISM /online /Get-CurrentEdition”。如果是评估版&#xff0c;例如Standard&#xff0c;把“ServerStandardEval”中的Eval这四个字母去掉&#xff0c;就是你的当前版本。下图表明…