正则表达式

标签:   表达

1.什么是正则表达式

正则表达式:也称为规则表达式,英文名称Regular Expression,我们在程序中经常会缩写为regex或者regexp,专门用于进行**文本**检索、匹配、替换等操作的一种技术。
注意:正则表达式是一种独立的技术,并不是某编程语言独有的

2.正则表达式语法结构

常规手机号码验证过程
def validatePhone(phone):
    msg = "提示信息:请输入手机号码"
    if len(phone) == 11:
        #判断是否是156/178开头
        if phone.startswith("156") or phone.startswith("178"):
            #判断每个字符都是字符
            for num in phone:
                if not num.isdigit():
                    msg = "不能包含非法字符"
                    return msg
            msg = "手机号码合法"
        else:
            msg = "开头数字不合法"
    else:
        msg = "长度不合法"
    return msg

if __name__ == "__main__":
    phone1 = input("号码1")
    print(validatePhone(phone1))
用正则表达式来改造这段程序
import re
userphone = input("请输入手机号码:")
def check_phone(phone):
    regexp = r"^(156|178)$"
    if re.match(regexp,phone):
        return True
    else:
        return False

print(check_phone(userphone))

python中的正则表达式:
python提供的正则表达式处理模块re,提供了各种正则表达式的处理函数

字符串查询匹配的函数
re.match(reg,info):用于在开始位置匹配目标字符中符合正则表达式reg的字符,匹配成功会返回一个match对象,匹配不成功则返回None。从第一个开始匹配,如果第一个就不匹配,则直接返回None
re.search(reg,info):扫描整个字符串info,使用正则表达式reg进行匹配,匹配成功返回匹配的第一个match对象,匹配不成功则返回None,
re.findall(reg,info):扫描整个字符串info,将符合正则表达式reg的字符全部提取出来存放在列表中返回
re.fullmatch(reg,info):扫描整个字符串,如果整个字符串都包含在正则表达式表示的范围中,返回整个字符串,否则返回None
re.finditer(reg,info):扫描整个字符串,返回的不是列表,是生成器
import re
my_str = "hello world"
rg1 = r"l"
print(re.match(rg1, my_str))   None
print(re.search(rg1, my_str))  <_sre.SRE_Match object; span=(2, 3), match='l'>
print(re.findall(rg1, my_str)) <callable_iterator object at 0x0000026684C476D8>['l', 'l', 'l'] 
print(re.finditer(rg1, my_str))
for x in re.finditer(rg1, my_str):
    print(x)  <_sre.SRE_Match object; span=(2, 3), match='l'>
<_sre.SRE_Match object; span=(3, 4), match='l'>
<_sre.SRE_Match object; span=(9, 10), match='l'>

字符串拆分替换的函数:

re.split(reg,string):使用指定的正则表达式reg匹配的字符,将字符串string拆分成一个字符串列表,如:re.split(r"\s+", info),表示使用一个或者多个空白字符对字符串info进行拆分,并返回一个拆分后的字符串列表
re.sub(reg,repl,string):使用指定的字符串repl来替换目标字符串string中匹配正则表达式reg的字符
import re
my_str = "hello world from"
reg = r"l"
print(re.split(reg,my_str))
print(re.sub(reg,"*",my_str))
['he', '', 'o wor', 'd from']
he**o wor*d from

正则表达式中的元字符:

这里写图片描述

代码实例:
import re
#定义测试文本字符串,下面还要用到
msg1 = """Python is an easy to learn, powerful programming language. 
It has efficient high-level data structures and a simple but effective approach to object-oriented programming. 
Python’s elegant syntax and dynamic typing, together with its interpreted nature, 
make it an ideal language for scripting and rapid application development in many areas on
"""
msg2 = "hello"
msg3 = "hello%"
#定义正则表达式,
resstart = r"efficient"
print(re.match(resstart,msg1))
print(re.search(resstart,msg1))
print(re.findall(resstart,msg1))
for i in re.finditer(resstart,msg1):
    print("->"+i.group())
print(re.fullmatch(r"\w*",msg2))
print(re.fullmatch(r"\w*",msg3))
结果:
None
<_sre.SRE_Match object; span=(67, 76), match='efficient'>
['efficient']
->efficient
<_sre.SRE_Match object; span=(0, 5), match='hello'>
None

正则表达式中的量词:用于限定数量的特殊字符
这里写图片描述

代码实例:
#导入正则表达式
import re
#测试文本
msg1 = "goodgoodstudy!,dooodooooup"
#匹配单词o出现0次或者多次的情况
print(re.findall(r"o*",msg1))
# 匹配一段字符串中出现单词o字符1次或者多次的情况
print(re.findall(r"o+",msg1))
# 匹配一段字符串中出现单词o字符0次或者1次的情况
print(re.findall(r"o?",msg1))
# 匹配字符串中连续出现2次字符o的情况
print(re.findall(r"o{2}",msg1))
# 匹配字符串中连续出现2次以上字符o的情况
print(re.findall(r"o{2,}",msg1))
# 匹配字符串中连续出现2次以上3次以内字符o的情况
print(re.findall(r"o{2,3}",msg1))
结果:
['', 'oo', '', '', 'oo', '', '', '', '', '', '', '', '', '', 'ooo', '', 'oooo', '', '', '']
['oo', 'oo', 'ooo', 'oooo']
['', 'o', 'o', '', '', 'o', 'o', '', '', '', '', '', '', '', '', '', 'o', 'o', 'o', '', 'o', 'o', 'o', 'o', '', '', '']
['oo', 'oo', 'oo', 'oo', 'oo']
['oo', 'oo', 'ooo', 'oooo']
['oo', 'oo', 'ooo', 'ooo']

正则表达式中的范围匹配:在正则表达式中,针对字符的匹配,除了快捷的元字符的匹配,还有另一种使用方括号进行的范围匹配方式,具体如下:
这里写图片描述

代码实例:
import re
msg = "Hello, The count of Today is 800"
#匹配所有的数字
print(re.findall(r"[0-9]+",msg))
# 匹配字符串msg中所有的小写字母
print(re.findall(r"[a-z]+",msg))
# 匹配字符串msg中所有的大写字母
print(re.findall(r"[A-Z]+",msg))
# 匹配字符串msg中所有的字母
print(re.findall(r"[a-zA-Z]+",msg))结果:
['800']
['ello', 'he', 'count', 'of', 'oday', 'is']
['H', 'T', 'T']
['Hello', 'The', 'count', 'of', 'Today', 'is']

正则表达式中的分组:

正则表达式主要是用于进行字符串检索匹配操作的利器
在一次完整的匹配过程中,可以将匹配到的结果进行分组,这样就更加的细化了我们对匹配结果的操作

这里写图片描述

代码实例
# 引入正则表达式模块
import re

# 用户输入座机号码,如"010-6688465"
phone = input("请输入座机号码:")
# 1.进行正则匹配,得到Match对象,对象中就包含了分组信息
res1 = re.search(r"^(\d{3,4})-(\d{4,8})$",phone)
# 查看匹配结果
print(res1)
# 匹配结果为默认的组,可以通过group()或者group(0)获取
print(res1.group())
# 获取结果中第一个括号对应的组数据:处理区号
print(res1.group(1))
# 获取结果中第二个括号对应的组数据:处理号码
print(res1.group(2))
# 2.进行正则匹配,得到Match对象,对象中就包含了命名分组信息
res2 = re.search(r"^(?P<nstart>\d{3,4})-(?P<nend>\d{4,8})",phone)
# 查看匹配结果
print(res2)
# 匹配结果为默认的组,可以通过group()或者group(0)获取
print(res2.group(0))
# 通过名称获取指定的分组信息:处理区号
print(res2.group("nstart"))
# 通过名称获取指定分组的信息:处理号码
print(res2.group("nend"))
结果:
请输入座机号码:021-658454
<_sre.SRE_Match object; span=(0, 10), match='021-658454'>
021-658454
021
658454
<_sre.SRE_Match object; span=(0, 10), match='021-658454'>
021-658454
021
658454

正则表达式的特殊用法:
这里写图片描述
正则表达式的贪婪模式和懒惰模式:

在某些情况下,我们匹配的字符串出现一些特殊的规律时,就会出现匹配结果不尽如人意的意外情况
如:在下面的字符串中,将div标签中的所有内容获取出来
<div>内容1</div><p>这本来是不需要的内容</p><div>内容2</div>
此时,我们想到的是,使用<div>作为关键信息进行正则表达式的定义,如下:
regexp = r"<div>.*</div>"
本意是使用上述代码来完成div开始标签和结束标签之间的内容匹配,但是,匹配的结果如下:
<div> [内容1</div><p>这本来是不需要的内容</p><div>内容2] </div>
我们可以看到,上面匹配的结果,是将字符串开头的<div>标签和字符串结束的</div>当成了匹配元素,对包含在中间的内容直接进行了匹配,也就得到了我们期望之外的结果:
内容1</div><p>这本来是不需要的内容</p><div>内容2
 上述就是我们要说的正则表达式的第一种模式:贪婪模式
 贪婪模式:正则表达式匹配的一种模式,速度快,但是匹配的内容会从字符串两头向中间搜索匹配(比较贪婪~),一旦匹配选中,就不继续向字符串中间搜索了,过程如下:
  开始:<div>内容1</div><p>这本来是不需要的内容</p><div>内容2</div>

第一次匹配:【<div>内容1</div><p>这本来是不需要的内容</p><div>内容2</div>】

  第二次匹配<div>【内容1</div><p>这本来是不需要的内容</p><div>内容2】</div>

匹配到正则中需要的结果,不再继续匹配,直接返回匹配结果如下:
内容1</div><p>这本来是不需要的内容</p><div>内容2

懒惰模式:

正则表达式匹配的另一种模式,会首先搜索匹配正则表达式开始位置的字符,然后逐步向字符串的结束位置查找,一旦找到匹配的就返回,然后接着查找
    regexp = r"<div>.*?</div>"
    开始:<div>内容1</div><p>这本来是不需要的内容</p><div>内容2</div> 第一次匹配:【<div>】内容1</div><p>这本来是不需要的内容</p><div>内容2</div> 第二次匹配【<div>内容1</div><p>这本来是不需要的内容</p><div>内容2</div> 匹配到正则中需要的结果:内容1 继续向后查找 第三次匹配<div>内容1</div><p>这本来是不需要的内容</p><div>内容2</div> 第四次匹配<div>内容1</div><p>这本来是不需要的内容</p><div>内容2</div>】 匹配到正则中需要的结果:内容2 
查找字符串结束!

这里写图片描述

原文链接:加载失败,请重新获取