IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 【python学习】正则表达式浅谈 -> 正文阅读

[Python知识库]【python学习】正则表达式浅谈

目录

正则表达式入门

代词

量词

范围符号[XXX]

|:或

边界符号

?+符号

注意事项

正则表达式的函数

re.match函数

re.search函数

re.findall函数

分组

分组的基本性质

分组与findall函数

贪婪模式和懒惰模式

习题练习!

1.找出所有整数和小数

2.找出小于100的整数

3 密码判断

4 寻找h3

5 找<>中的数

6 电话号码

?


什么是正则表达式?

在日常生活中,我们经常会遇到设置密码的问题,系统需要判断我们设置的密码是否符合规定的要求;在微信聊天时,我们时常需要寻找含有某些关键词的聊天记录或者文件名称;在文档处理时,我们常常需要提取出符合某种特征的特定语句,显然,人工寻找是完全不现实的。在以上三个例子中,我们都会用到正则表达式。简而言之,正则表达式是一种判断字符串是否符合某种模式的表达式,它的用途非常广泛,我们可以用它来在文本中寻找并提取出符合某种模式的字符串。

例如,为了判断BNU21级数科新生的学号输入是否正确,我们可以提取出学号的正则表达式"20211113[0-9][0-9][0-9][0-9]",然后就能判断学号的输入是否正确了。

正则表达式入门

正则表达式的表达方式很简单,就是一个字符串。该字符串内由符号和内容组成,可以根据正则表达式的规则来生成你想要达到的字符串模式。例如可以用 "[1-9]\d*" (具体含义后面会写)来匹配所有的正整数。

下面总结一下正则表达式的匹配规律:

首先,无特殊含义的字符匹配本身,如"abc"匹配字符串"abc",这是最简单的匹配。但是实际运用中需要大量其他的条件,因此有了功能字符。

代词

顾名思义,用功能字符来代替某一类字符,从而简化了表达。

常用代词
\d数字字符,即[0-9]
\D非数字字符,即[^/d]或[^0-9]
\s空白字符,如\t,\n,\r等
\S非空白字符
\w单词字符:汉字,大小写字母,数字,下划线均可
\W非单词字符
.除\n外的任何一个字符

量词

同样出于简化的目的,有的时候我们需要匹配多个重复的字符,例如6个数字字符,这时候如果把\d写6遍显然太复杂,所以引出了量词。其作用是控制量词左边的字符的重复次数。

注意,量词的作用对象仅限于量词左侧的字符。

常用量词
*左边字符出现0或任意次
左边字符出现0或1次
+左边字符出现至少1次
{m}左边字符出现恰好m次
{m,n}

左边字符出现至少m次至多n次,n可不写表示无上限

范围符号[XXX]

范围符号表示要匹配一个范围,属于该范围内的字符均能成功匹配。

[Ab3]匹配字符'A','b','3'之一
[5-9]匹配字符'5'-'9'之一
[a-d5-9]匹配字符'a'-'d','5'-'9'之一
[^a-z]匹配非(^)小写字母的字符

根据代词、量词和范围符号,我们就能理解为什么正整数的正则表达式是"[1-9]\d*"了

|:或

经典逻辑符号或与非在正则表达式里也有用到!(果然语言都是相通的)

简单举几个例子:

"[a-z]{3}|\d{3}" 匹配任意三个连续小写字母或者三个数字

"\w{3}a|b\d{2}|cd\w" 可以匹配:"abca","b12","cdg"等

需要注意的是,|会短路匹配,顺序是从左到右。

边界符号

除了对匹配的字符串本身有要求,有时候我们还希望匹配到的字符串的前后的字符也要满足特定条件,这时候我们就引入了边界符号来对字符串前后的字符做一定的限制。

\A左边界,要求字符串往左不能有字符
^同\A,多行匹配模式下还可以表示一行文字的左边界
\Z右边界,要求字符串往右不能有字符
$同\Z,多行匹配模式下还可以表示一行文字的左边界
\b表示此处应为单词的左/右边界,即不能为单词字符
\B表示此处不允许为单词的左/右边界,即必须是单词字符

?+符号

?的不仅仅具有量词的功能,还具有类似于边界符号的功能。

有时候我们需要对字符串的前/面进行限制,例如:我们要找放在数字中间的一串小写字母,也就是要求我们不仅仅要寻找一串小写字母,还要判断这串小写字母的前后是否都是数字。这时我们就需要正向/反向预查。

(?=pattern)正向肯定预查,表达式右边必须满足pattern
(?!pattern)正向否定预查,表达式右边必不能满足pattern
(?<=pattern)反向肯定预查,表达式左边必须满足pattern
(?<!pattern)反向否定预查,表达式右边必不能满足pattern

因此,要匹配放在数字中间的一串小写字母,正则表达式可写为:"(?<=\d)[a-z]+(?=\d)"

注意事项

如果要在正则表达式中表示特殊符号本身,则应该在其前面加'\'

正则表达式里的特殊符号很多,后面如果学到了会继续补充。

正则表达式的函数

首先,使用正则表达式要引用re库

import re

下面是使用正则表达式的几种常用函数

re.match函数

格式:re.match(pattern,string,flags)

如果匹配失败则返回None,匹配成功则返回匹配到的字符串

pattern是正则表达式,string是要匹配的字符串,flags是标志位

需要注意的是,re.match函数从string的起始位置开始匹配!

import re
x=re.match("[1-9]\d*","123abd")
if x!=None:
    print(x.group())
else:
    print("none")
y=re.match("[1-9]\d*","c123ad")
if y!=None:
    print(y.group())
else:
    print("none")
#输出结果:
123
none

re.search函数

格式:re.search(pattern,string,flags)

查找可匹配成功的字符串,返回(第一个)匹配对象或None

用group里包含匹配对象,span包含起止位置

import re
x = re.search("[1-9]\d*","asd234164jsj2341jkc")
if x != None:
    print(x.group(),x.span()) # 输出子串及起止位置
else:
    print("None")
#输出结果
234164 (3, 9)

re.findall函数

格式:re.findall(pattern,string,flags)

查找所有和pattern匹配的子串(不重叠),放入列表中

import re
lst = re.findall("[1-9]\d*","qw21313h1o58p4kjh8123jkh8435u")
for x in lst:
    print(x,end=" ")
#输出结果:21313 1 58 4 8123 8435 

分组

分组的基本性质

在正则表达式中加入括号可以对匹配到的字符串进行分组,目的是分离我们匹配到的字符串。多个分组左括号从左到右从1开始编号。

import re
m = "(([1-9])\d*)([a-z]{2})"
r = re.match(m,"3780qp")
if r !=None:
    print(r.groups())  # >>('3780', '3', 'qp')
    print(r.group(0))  # >>3780qp
    print(r.group(1))  # >>3780
    print(r.group(2))  # >>3
    print(r.group(3))  # >>qp
#r.group(0)相当于r.group()

同时,分组还具有另外一种简化正则表达式的功能,即我们可以在正则表达式中引用分组本身。在分组的右边可以通过分组的编号引用该分组所匹配的子串。并且,我们可以将分组看作一个整体,在分组的后面可以加量词(此时量词的作用范围就是整个分组)。例如:

import re
m = r"(((ab*)c)d)e\3" #r 表示字符串里的'\'不再转义
#要求ab*cde后面跟着3号分组在本次匹配中匹配上的子串
r = re.match(m,"abbcdeabbkfg") #kfg前面少一个b则不能匹配
print(r.group(3)) #>>abb
print(r.group())  #>>abbcdeabb

分组与findall函数

在前面已经知道,没有分组时,re.findall 返回所有匹配子串构成的列表。如果有且只有一个分组 那么re.findall 返回的是一个子串的列表,每个元素是一个匹配子串中分组对应的内容。如果有超过一个分组时,re.findall返回的是一个元组的列表,每个元组对应于一个匹配的子串,元组里的元素依次是1 号分组、2 号分组、3 号分组......

后面的习题里会用到

贪婪模式和懒惰模式

贪婪模式,即量词+,*,?,{m,n}等默认匹配尽可能长的子串

如果在上述量词后加?则会匹配可能短的子串,即为懒惰模式

习题练习!

终于进入紧张刺激的实际演练环节了!

1.找出所有整数和小数

openjudge链接

题目描述:给一段文字,可能有中文,把里面的所有非负整数和小数找出来,不需要去掉前导0或小数点后面多余的0, 然后依次输出。

输入:一段文字

输出:按顺序输出所有整数和小数,每个整数一行

分析:写出非负整数、小数的正则表达式,再套用对应的函数即可。

import re
m="\d+\.\d+|\d+"
while True:
    try:
        s = input()
        lst = re.findall(m,s)
        for x in lst:
            print(x)
    except:
        break

2.找出小于100的整数

题目描述:有给定的两行输入,在每一行的输入中提取在[0,100)内的整数(不包括100)并依次输出。注意要排除负数。(题目不会包含00)

import re
m = r"(^|[^0-9-])(\d{1,2})([^0-9]|$)"
for i in range(2):
        s = input()
        lst = re.findall(m,s)
        for x in lst:
// 在此处补充你的代码

样例输入:

12高兴-23大小256的数1234好啊24对的好0这个1这个2这个12这个134这个0123这个12
123高兴-23大小256的数1234好啊24对的23这

样例输出:

12
24
0
1
2
12
12
24
23

分析:100以内的整数,即是由两个数字字符组成的,并且左边和右边都不能出现整数。这道题已经给出了代码,实际上是用分组实现的。100以内的整数存储在第二组,也就是x[1]中,所以补充后的代码即为:

import re
m = r"(^|[^0-9-])(\d{1,2})([^0-9]|$)"
for i in range(2):
        s = input()
        lst = re.findall(m,s)
        for x in lst:
            print(x[1])

3 密码判断

题目描述:用户密码的格式是: 1) 以大写或小写字母开头 2) 至少要有8个字符,最长不限 3) 由字母、数字、下划线或 '-' 组成 输入若干字符串,判断是不是符合密码的条件。如果是,输出 yes 如果不是,输出 no

import re
// 在此处补充你的代码
while True:
    try:
        s = input()
        if re.match(m,s) != None:
            print("yes")
        else:
            print("no")
    except:
        break

输入:若干行

输出:对每行输入,判断其是否符合密码格式,相应地输出 yes 或no

分析:把密码的正则表达式写出来就行了

import re
m="^[a-zA-Z][a-zA-Z0-9_-]{7,}$"
#注意要添加边界符号
while True:
    try:
        s = input()
        if re.match(m,s) != None:
            print("yes")
        else:
            print("no")
    except:
        break

4 寻找h3

题目描述:程序填空,输出指定结果

import re
m = \
// 在此处补充你的代码
for x in  re.findall(m,"cdef<h3>abd</h3><h3>bcK</h3><h3>123</h3>KJM"):
    print(x)

输出:

abd
bcK
123

分析:即为找出<h3>与</h3>之间的部分,这里用到了正向肯定预查和反向肯定预查。即对我们要寻找的字符串,其前面必须是<h3> (?<=<h3>) 后面必须是</h3> (?=</h3>)

import re
m = \
r"(?<=<h3>)\w+(?=</h3>)"
for x in  re.findall(m,"cdef<h3>abd</h3><h3>bcK</h3><h3>123</h3>KJM"):
    print(x)

5 找<>中的数

题目描述:输入一串字符,将输入中的,在<>里面的,没有前导0的少于4位的整数依次输出。单独的0也要输出。

输入:第一行是整数n,表示后面一共有n个字符串。接下来有n行字符串

输出:对每个字符串,输出题目要求的结果

分析:写出对应的正则表达式,前面是<,后面是>,用到正向反向预查语句

正则表达式即为: r"(?<=<)(0{1}|[1-9]\d{0,2})(?=>)"

然后模拟一下整个过程即可

import re
m=r"(?<=<)(0{1}|[1-9]\d{0,2})(?=>)"
n=int(input())
for i in range(n):
    x=input()
    y=re.findall(m,x)
    if y==[]:
        print("NONE",end=" ")
    else:
        for o in y:
            print(o,end=" ")
    print("")

6 电话号码

题目描述:

输入:有多组数据,每组一行

输出:对每组数据, 抽取出其中的tag及其包含的电话号码中的区号输出。每个tag输出为一行。tag外的电话号码不用理会。如果找不到tag及其包含的电话号码, 则输出NONE。数据保证不会出现两个tag重叠的情况。

提示:

1) tag中间可以有任何文字,比如 <ab>xddd</cd></ab>也是一个合法tag
2) 在分组的右边可以通过分组的编号引用该分组所匹配的子串
m = r'(((ab*)c)d)e\3' #要求 ab*cde后面跟着第三分组的内容
r = re.match(m,"abbbcdeabbbkfg") # 后面的bbb少一个b则不能匹配,因为第三分组是abbb
print(r.group(3)) # abbb
print(r.group()) # abbbcdeabbb
3) 如果一个正则表达式搞不定,可以先用一个正则表达式抽取某个中间结果,再在中间结果里面手工或者用另外的正则表达式进一步分析

分析:题目相当于由两步,第一步是提取出所有tag,第二步是在tag里面找出电话号码。稍微有点麻烦的是要做好标记(以便于判断是否输出NONE)

这两步显然都需要用到正则表达式,所以可以先把对应的正则表达式写好。抽取tag显然要用到分组(因为要求两个X的内容相同)这道题用好分组也可以减省一些步骤。

实现过程会有点麻烦,可以多调试一下。

import re
m=r"(<([a-z]+)>.+?</\2>)" #tag
b=r"\((\d{1,2})\)-\d{3}(?=[^\d])" #电话号码
n=int(input())
for i in range(n):
    s=input()
    k=re.findall(m,s)#找到所有tag
    flag=0
    for x in k:
        y=re.findall(b,x[0])
        l=len(y)
        if l !=0:
            flag=1
            print('<'+x[1]+'>'+y[0],end="")
            for j in range(1,l,1):
                print(','+y[j],end="")
            print("</"+x[1]+'>')
    if flag==0:
        print("NONE")

以上就是正则表达式全部内容,后面也许还会有补充。

  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-08-31 15:24:46  更:2021-08-31 15:25:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 11:32:49-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码