正则表达式

官方定义:正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个 “规则字符串”,这个 “规则字符串” 用来表达对字符串的一种过滤逻辑。

我们先来看一个正则与 re 模块的例子

判断手机号是否合法

#while 实现
while True:
phone_number = input('please input your phone number : ')
if len(phone_number) == 11 \
and phone_number.isdigit()\
and (phone_number.startswith('') \
or phone_number.startswith('') \
or phone_number.startswith('') \
or phone_number.startswith('')):
print('是合法的手机号码')
else:
print('不是合法的手机号码')
#re 模块实现
import re
phone_number = input('please input your phone number : ')
if re.match('^(13|14|15|18)[0-9]{9}$',phone_number):
print('是合法的手机号码')
else:
print('不是合法的手机号码')

字符组

用法:[字符组]

在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用 [] 表示
字符分为很多类,比如数字、字母、标点等等。
假如你现在要求一个位置 " 只能出现一个数字 ",那么这个位置上的字符只能是 0、1、2...9 这 10 个数之一。

字符

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

量词

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

.*? 的用法

关键字符 用法说明
. 是任意字符
* 是取 0 至 无限长度
? 非贪婪模式

合在一起就是 取尽量少 的任意字符,一般不会这么单独写,他大多用在:(.*?x)取前面任意长度的字符,直到一个x出现的时候

其他重要的字符

字符 用法说明
\ 转义符
{...} {1,2}匹配 1 到 2 次任意字符

贪婪匹配

贪婪格式 用法说明
<.*> 默认为贪婪匹配模式,会匹配尽量长的字符串
<.*?> 加上 ?为将贪婪匹配模式转为非贪婪匹配模式,会匹配尽量短的字符串

几个常用的非贪婪匹配(Pattern)

格式 用法
*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}?  重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复

模块

re 模块

三个非常重要的方法:findall、search、match

findall(找所有)
返回所有满足匹配条件的结果,放在列表里

#findall
ret = re.findall('a','eva egon yuan')
print(ret) ret = re.findall('[a-z]+','eva egon yuan')
print(ret)

获取式子中的整数

#获取整数
ret=re.findall(r"\d+\.\d+|(\d+)","1-2*(60+(-40.35/5)-(-4*3))")
print(ret) #['1', '2', '60', '40', '35', '5', '4', '3']
ret.remove('')
print(ret)

search(找一个)
从前往后,找到一个就返回,返回的变量需要调用 group 才能拿到结果
如果没有找到,那么返回 None,调用 group 会报错

#search
ret = re.search('a', 'eva egon yuan').group() #当不使用 group() 调用时,返回的是一个结果的对象
print(ret) ret = re.search('a', 'eva egon yuan')
print(ret) #没有找到值 会报错
ret = re.search('j', 'eva egon yuan').group()
print(ret) #search 的一般用法
ret = re.search('a', 'eva egon yuan')
if ret:
print(ret.group())
#search 结合分组的用法
ret = re.search('^[1-9](\d{14})(\d{2}[0-9x])?$','')
print(ret.group())
print(ret.group(1)) #取出第一组
print(ret.group(2)) #取出第二组

给分组命名

#可以在分组中利用?<name>的形式给分组起名字
#获取的匹配结果可以直接用group('名字')拿到对应的值
ret = re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")
print(ret.group())
print(ret.group(1))
print(ret.group('tag_name')) ret = re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>")
#如果不给组起名字,也可以用\序号来找到对应的组,表示要找的内容和前面的组内容一致
#获取的匹配结果可以直接用group(序号)拿到对应的值
print(ret.group(1))
print(ret.group()) #结果 :<h1>hello</h1>

match(从头开始找一个) 用法 search 基本一致
match是从头开始匹配,如果正则规则从头开始可以匹配上,就返回一个变量。
匹配的内容需要用 group 才能显示,如果没匹配上,就返回 None,调用 group 时会报错

#match
ret = re.match('a','eva egon,yuan') #没有匹配到
if ret:
print(ret.group()) ret = re.match('e','eva egon,yuan') #匹配到了
if ret:
print(ret.group()) ret = re.match('[a-z]','eva egon,yuan') #匹配到了
if ret:
print(ret.group())

其他重要的方法

方法:split、sub、subn、compile、finditer、split、flags

split
先按 'a' 分割得到 '' 和 'bcd',在对 '' 和 'bcd' 分别按 'b' 分割

#split
ret = re.split('[ab]','abcd')
print(ret) # ['', '', 'cd']

sub
将数字替换成 'H',参数 1 表示只替换 1 个,不写表示替换全部

#sub
ret = re.sub('\d', 'H', 'eva3egon4yuan4',1)
print(ret) #evaHegon4yuan4

subn
将数字替换成 'H',返回元组 ( 替换的结果,替换了多少次 )

#subn
ret = re.subn('\d', 'H', 'eva3egon4yuan4')
print(ret)

compile
一般用于一条正则规则要反反复复使用或一条规则特别长的时候使用

#compile
#将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
obj = re.compile('\d{3}')
ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串
print(ret.group()) #结果 : 123
ret = obj.search('abcashgjgsdghkash456eeee3wr2') #正则表达式对象调用search,参数为待匹配的字符串
print(ret.group()) #结果 : 456

finditer
返回一个存放匹配结果的迭代器,当所找的东西很多时

#finditer
ret = re.finditer('\d', 'ds3sy4784a')
print(ret) # <callable_iterator object at 0x10195f940>
# print(next(ret).group()) #查看第一个结果
# print(next(ret).group()) #查看第二个结果
# print([i.group() for i in ret]) #查看剩余的左右结果
for i in ret:
print(i.group()) # .group()可以取出所有值

分组优先的问题

findall 存在的问题
这是因为 findall 会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可

#findall 取值的问题
ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com')
print(ret) # ['oldboy'] # 这里使用 ? 来取消分组优先
ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com')
print(ret) # ['www.oldboy.com']

split的优先级查询

#split 应该注意的问题
ret=re.split("\d+","eva3egon4yuan")
print(ret) #结果 : ['eva', 'egon', 'yuan'] ret=re.split("(\d+)","eva3egon4yuan")
print(ret) #结果 : ['eva', '3', 'egon', '4', 'yuan'] #在匹配部分加上()之后所切出的结果是不同的,
#没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项,
#这个在某些需要保留匹配部分的使用过程是非常重要的

转义的问题

# r 转义
import re
ret = re.findall(r'\\s',r'\s')
print(ret)

flags 有很多可选值:

可选值 说明
re.I (IGNORECASE) 忽略大小写,括号内是完整的写法
re.M (MULTILINE) 多行模式,改变^和$的行为
re.S (DOTALL) 点可以匹配任意字符,包括换行符
re.L (LOCALE) 做本地化识别的匹配,表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境,不推荐使用
re.U (UNICODE) 使用 \w \W \s \S \d \D 使用取决于 unicode 定义的字符属性。在 python3 中默认使用该 flag
re.X (VERBOSE) 冗长模式,该模式下 pattern 字符串可以是多行的,忽略空白字符,并可以添加注释

  
     
          
     
     
  

day 18 - 1 正则与 re 模块的更多相关文章

  1. day 18 - 2 正则与 re 模块练习

    1.爬虫的例子 #爬虫的例子(方法一) import re import urllib,request import urlopen def getPage(url): response = urlo ...

  2. day19 正则,re模块

    http://www.cnblogs.com/Eva-J/articles/7228075.html  所有常用模块的用法 正则的规则: 在一个字符组里面枚举合法的所有字符,字符组里面的任意一个字符和 ...

  3. 正则,re模块

    一.正则表达式(精准匹配) 匹配字符串内容的一种规则 二.字符组 在同一个位置可能出现的各种字符组成了一个字符组,在正则表达式中用[]表示 常见字符组格式如下:[0123456789],[0-9],[ ...

  4. python正则以及collections模块

    正则 一.认识模块  什么是模块:一个模块就是一个包含了python定义和声明的文件,文件名就是加上.py的后缀,但其实import加载的模块分为四个通用类别 : 1.使用python编写的代码(.p ...

  5. Python 正则处理_re模块

    正则表达式 动机 文本处理成为计算机常见工作之一 对文本内容搜索,定位,提取是逻辑比较复杂的工作 为了快速方便的解决上述问题,产生了正则表达式技术 定义 文本的高级匹配模式, 提供搜索, 替换, 本质 ...

  6. Learning-Python【18】:Python常用模块(1)—— time、datetime、randrom

    time 模块:与时间相关的功能的模块 在 Python 中,时间分为三种: 1.时间戳:是一个时间的表示,根据不同的语言,可以是整数或浮点数,是从1970年1月1日0时0分0秒到现在经历的秒数 2. ...

  7. day23 正则,re模块

    一. 简谈正则表达式 元字符 . 除了换行符外任意字符. \w 数字.字母.下划线 \s 空白符 \b 单词的末尾 \d 数字 \n 匹配换行符 \t 匹配制表符 \W 除了数字. 字母 下划线 \D ...

  8. python 基础之第十二天(re正则,socket模块)

    In [14]: 'hello-wold.tar.gz'.split('.') Out[14]: ['hello-wold', 'tar', 'gz'] In [15]: import re In [ ...

  9. Python正则、re模块

    正则的概念 findall        match        search  方法 元字符的用法和作用 正则表达式概念 正则表达式是对字符串操作的一种逻辑公式,就是对字符串的一种过滤 可以判断是 ...

随机推荐

  1. Java线程锁,synchronized、wait、notify详解

    (原) JAVA多线程这一块有点绕,特别是对于锁,对锁机制理解不清的话,程序出现了问题也很难找到原因,在此记录一下线程的执行以及各种锁. 1.JAVA中,每个对象有且只有一把锁(lock),也叫监视器 ...

  2. day6-基础函数的学习(一)

    今日份目录 1.函数的定义 2.函数的返回值 3.函数的参数 4.函数的局部变量与全局变量 5.名称空间与作用域 6.global与nonlocal 7.高阶函数 继续今日份总结!这个总结也晚了,哎, ...

  3. Linux系统中常见的目录名称以及相应内容

    目录名称 应放置文件的内容 /boot 开机所需文件——内核.开机菜单以及所需配置文件等等 /dev 以文件形式存放任何设备与接口 /etc 配置文件 /home 用户家目录 /bin 存放单用户模式 ...

  4. ARC089E GraphXY 构造

    传送门 在Luogu上评了"NOI"之后评级变成了"普及+/提高"--我觉得我可能要退群了 考虑构造一个这样的图: 其中上半部分是从\(S\)开始的一条长\(1 ...

  5. BZOJ3709 Bohater 贪心

    传送门 思路很妙-- 有个前提条件:血量无限,这样话肯定先打会回血的怪,再打会掉血的怪 对于会回血的怪,按照受到伤害的顺序从小往大打 对于会掉血的怪似乎并不是很好搞,考虑:将每一时刻的血量函数画出来, ...

  6. Django配置404页面

    一.settings配置 1.首先需要在settings中将DEBUG由原来的True改为False DEBUG = False 2.需要设置 ALLOWED_OSTS = ["*" ...

  7. react-navigation 简介

    StackNavigator: 原理和浏览器相似但又有局限,浏览器的方式是开放性的,通过点击一个链接可以跳转到任何页面(push),点击浏览器后退按钮,返回到前一个页面(pop).StackNavig ...

  8. java 中的基本数据类型

    1,  变量 Java是强类型语言, 对于每一种数据都定义了类型,基本数据类型分为数值型,字符型,布尔型.数值型又分为了整型和浮点型. 整型又分为byte, int, short long. 浮点型又 ...

  9. 一种使用 sprintf 导致死机的情况

    @2019-02-26 [小记] char temp[10] float money; sprintf(temp, "0.2f", money); 以上使用方法可能导致死机,原因是 ...

  10. 一丢丢学习之webpack4 + Vue单文件组件的应用

    之前刚学了一些Vue的皮毛于是写了一个本地播放器https://github.com/liwenchi123000/Local-Music-Player,如果觉得ok的朋友可以给个star. 就是很简 ...