郭炜老师mooc第九章正则表达式

2024-03-09 14:20

本文主要是介绍郭炜老师mooc第九章正则表达式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

正则表达式

正则表达式是个某些字符有特殊含义字符串,表示一种字符串的模式(格式)

正则表达式中的功能字符

  •  d:digit
  • s:space
  • w:word

 花括号量词{m,n},逗号后面要紧跟数字,不能打空格,否则输出结果和你想象的不一样,当然我并不知道为什么!

import re
pt = "\d{1, 3}"
print(re.findall(pt, "1234567890"))pt = "\d{1,3}"
print(re.findall(pt, "1234567890"))pt = "\d*"
print(re.findall(pt, "1234567890"))

输出结果:

[]
['123', '456', '789', '0']
['1234567890', '']

 正则表达式中的特殊字符

正则表达式中常见的特殊字符有以下几个:
. + ? * $ [ ] ( ) ^ { } \
如果要在正则表达式中表示这几个字符本身,就应该在其前面加'\'。

 范围符号[XXX]的用法

用以表示“此处必须出现一个某某范围内的字符”,或者“此处必须出现一个字符,但不可以是某某范围内的字符”

 量词(+,*,?)的用法

使用正则表达式需要:模块re

 re模块是python独有的匹配字符串的模块,该模块种提供功能基于正则表达式实现的,对于字符串进行模糊匹配找到想要的内容信息,一般用于爬虫或者自动化测试前后端不分离项目。

 re.match函数

# re.match函数import re
def match(pattern,string):x = re.match(pattern,string)if x != None:print(x.group()) #x.group是匹配上的字符串else:print("None")match("a c","a cdkgh") #>>a c
match("abc","kabc") #>>None 虽然有abc,但不是在起始位置
match("a\tb*c","a\tbbcde") #>>a bbc b出现0次或任意多次,然后跟c
match("ab*c","ac") #>>ac
match("a\d+c","ac") #>>None b出现1次或更多次,然后跟c
match("a\d{2}c","a34c") #>>a34c
match("a\d{2,}c","a3474884c") #>>a3474884c
match(".{2}bc","cbcd") #>>None bc前面要有2个字符

 re.search函数

re.search(pattern, string, flags = 0)

  • 查找字符串中可以匹配成功的子串。若匹配成功,则返回匹配对象;
  • 若无法匹配,则返回None
# re.search函数import re
def search(pattern,string):x = re.search(pattern,string)if x != None:print(x.group(),x.span()) #输出子串及起止位置else:print("None")search("a.+bc*","dbaegsfbcef") #>>aegsfbc (2, 9)
search("a.+bc*","bcdbaegsfbccc") #>>aegsfbccc (4, 13)
search("a.?bc*d","dabccdc") #>>abccd (1, 6)
search("aa","baaaa") #>>aa (1, 3)
search("\([1-9]+\)","ab123(0456)(789)45ab") #>>(789) (11, 16)
search("[1-9]\d+","ab01203d45") #>>1203 (3, 7)

re.findall函数

re.findall(pattern, string, flags = 0)

  • 查找字符串中所有和模式匹配的子串(不重叠)放入列表。一个子串都找不到
    就返回空表 []
# re.finall函数import re
print(re.findall('\d+',"this is 334 what me 774gw")) #>>['334','774']
print(re.findall('[a-zA-Z]+',"A dog has 4 legs.这是true"))
#>>['A', 'dog', 'has', 'legs', 'true']
print(re.findall('\d+',"this is good.")) #>>[]
print(re.findall("aaa","baaaa")) #>>['aaa']

re.finditer函数

re.finditer (pattern, string, flags = 0)

  • 查找字符串中所有和模式匹配的子串(不重叠),每个子串对应于一个匹配对象,返回匹配对象的序列(准确说是“可调用迭代器”)
  • 如果找不到匹配子串,返回值也不为None或空表。假设返回值为r,则list(r) 为[]
# re.finditer函数import re
s = '233[32]88ab<433>(21)'
m = '\[\d+\]|<\d+>' # | 表示 '或'
for x in re.finditer(m,s): #x是匹配对象print(x.group(),x.span())
# [32] (3, 7)
# <433> (11, 16)i = 0
for y in re.finditer(m,"aaaaa"):i += 1 #不会被执行

 正则表达式匹配选项

边界符号

  • \A 表示字符串的左边界,即要求从此往左边不能有任何字符
  • \Z 表示字符串的右边界,即要求从此往右边不能有任何字符
  • ^ 与\A同。但多行匹配模式下还可以表示一行文字的左边界
  • $ 与\Z同。但多行匹配模式下还可以表示一行文字的右边界

边界符号本身不会和任何字符匹配。
Python字符串 '\A', '\Z' 都是两个字符,而不是像'\n'那样的一个字符。

  • \b 表示此处应为单词的左边界或右边界,即不可是单词字符
  • \B 表示此处不允许是单词的左边界或右边界,即必须是单词字符
  •  正则表达式的边界符号'\b' 是两个字符。但是在Python字符串中,'\b'和'\t','\n'类似,是一个字符(Backspace)。因此在正则表达式中使用边界符号\b,要写 '\\b'。如果写 '\\\\b',则连续的两个'\'被看作是一个普通的'\',不会和后面的'b'一起被当作字符组合,变成边界符号'\b'。

分组

 括号中的表达式是一个分组。多个分组按左括号从左到右从1开始依次编号。

在Python中,正则表达式的group和groups方法是非常有用的函数,用于处理匹配结果的分组信息。
group方法是re.MatchObject类中的一个函数,用于返回匹配对象的整个匹配结果或特定的分组匹配结果。而groups方法同样是re.MatchObject类中的函数,它返回的是所有分组匹配结果组成的元组。

  • 当group方法不带参数时,它将返回整个匹配结果。该函数默认传参为0,传入参数0(默认值)将返回整个匹配的子串,而传入参数1将返回第一个匹配的捕获组(即正则表达式中用括号括起来的部分)。当正则表达式中包含分组时,group方法可以用于返回指定分组的匹配结果。
  • groups方法是re.MatchObject类的一个函数,用于返回所有分组匹配结果组成的元组。该方法不接受任何参数。

 参考文章:详解Python正则表达式中group与groups的用法_.group()-CSDN博客

 括号中的表达式是一个分组。多个分组按左括号从左到右从1开始依次编号。

# 括号中的表达式是一个分组。多个分组按左括号从左到右从1开始依次编号import re
x = re.search('[a-z]+(\d+)[a-z]+',"ab 123d hello553world47")
print(x) # >> <re.Match object; span=(8, 21), match='hello553world'>
print(x.group()) #>>hello553world
print(x.group(1)) #>>553
m = "(((ab*)c)d)e"
r = re.match(m,"abcdefg")
print(r.group(0)) #>>abcde group(0)等价于group()
print(r.group(1)) #>>abcd
print(r.group(2)) #>>abc
print(r.group(3)) #>>ab
print(r.groups()) #>>('abcd', 'abc', 'ab')

 在分组的右边可以通过分组的编号引用该分组所匹配的子串

# 在分组的右边可以通过分组的编号引用该分组所匹配的子串import re
m = r'(((ab*)c)d)e\3' #r表示字符串里的'\'不再转义
#要求 ab*cde后面跟着3号分组在本次匹配中匹配上的子串
r = re.match(m,"abbbcdeabbbkfg") # 红色部分少一个b则不能匹配
print(r.group(3)) # abbb
print(r.group()) # abbbcdeabbbr = re.match(m,"abbbcdeabbkfg")
print(r)  # None
# 在分组的右边可以通过分组的编号引用该分组所匹配的子串
import re
pt = 'a(.)\\1*b' #或 pt = r'a(.)\1*b'
print(re.search(pt,'kacccccb').group()) #>>acccccb
print(re.search(pt,'kaxxxxb').group()) #>>axxxxb
print(re.search(pt,'kaxb').group()) #>>axb
x = re.search(pt,'kaxyb')
if x != None:print(x.group()) #不会执行

 分组作为一个整体,后面可以跟量词

# 分组作为一个整体,后面可以跟量词import re
m = "(((ab*)+c)d)e"
r = re.match(m,"ababcdefg")
print(r.group())  # ababcde
print(r.groups()) #>>('ababcd', 'ababc', 'ab')
r = re.match(m,"abacdefg")
print(r.group()) # abacde
print(r.groups()) #>>('abacd', 'abac', 'a')# 不要求分组的多次出现必须匹配相同字符串

 re.findall和分组

  •  在正则表达式中没有分组时,re.findall返回所有匹配子串构成的列表
  • 有且只有一个分组时,re.findall返回的是一个子串的列表,每个元素是一个匹配子串中分组对应的内容。
'''
在正则表达式中没有分组时,re.findall返回所有匹配子串构成的列表。
有且只有一个分组时,re.findall返回的是一个子串的列表,每个元素是一个匹配子串中分组对应的内容。
'''import re
m = '[a-z]+(\d+)[a-z]+'
x = re.findall(m,"13 bc12de ab11 cd320ef")
print(x) #>>['12', '320']m = '[a-z]+\d+[a-z]+'
x = re.findall(m,"13 bc12de ab11 cd320ef")
print(x) #>>[['bc12de', 'cd320ef']
  •  在正则表达式中有超过一个分组时,re.findall返回的是一个元组的列表,每个元组对应于一个匹配的子串,元组里的元素,依次是1号分组、2号分组、3号分组......匹配的内容
'''
在正则表达式中有超过一个分组时,re.findall返回的是一个元组的列表,
每个元组对应于一个匹配的子串,元组里的元素,依次是1号分组、2号分组、
3号分组......匹配的内容
'''import re
m = '(\w+) (\w+)'
r = re.match(m,"hello world")
print(r.groups()) #>>('hello', 'world')
print(r.group(1)) #>>hello
print(r.group(2)) #>>world
r = re.findall(m,"hello world, this is very good")
#找出由所有能匹配的子串的 groups() 构成的元组,互相不重叠
print(r) #>>[('hello', 'world'), ('this', 'is'), ('very', 'good')]

 "|" 的用法

表示“或”,如果没有放在"()"中,则起作用范围是直到整个正则表达式开头或结尾或另一个 "|"

  • "\w{4}ce|c\d{3}|p\w"

可以匹配:
"c773"
"ab12ce"
"pk"

 从左到右短路匹配(匹配上一个后就不计算是否还能匹配后面的)

# "|" 的用法,从左到右短路匹配(匹配上一个后就不计算是否还能匹配后面的)import re
pt = "\d+\.\d+|\d+"
print(re.findall(pt,"12.34 this is 125"))
#>>['12.34', '125']
pt = "aa|aab"
print(re.findall(pt,"aabcdeaa12aab"))
#>>['aa', 'aa', 'aa']

 '|' 也可以用于分组中,起作用范围仅限于分组内

# '|' 也可以用于分组中,起作用范围仅限于分组内import re
m ="(((ab*)+c|12)d)e"
print(re.findall(m,'ababcdefgKK12deK'))
#>>[('ababcd', 'ababc', 'ab'), ('12d', '12', '')]
for x in re.finditer(m,'ababcdefgKK12deK'):print(x.groups())
#>>('ababcd', 'ababc', 'ab')
#>>('12d', '12', None)
m = '\[(\d+)\]|<(\d+)>'
for x in re.finditer(m,'233[32]88ab<433>'):print(x.group(),x.groups())
#>>[32] ('32', None)
#>><433> (None, '433')

贪婪模式和懒惰模式 

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

# 量词 +,*,?,{m,n} 默认匹配尽可能长的子串import re
print(re.match("ab*", "abbbbk").group()) #>>abbbb
print(re.match("(ab)*", "abbbbk").group()) #>>abprint(re.findall("<h3>(.*)</h3>","<h3>abd</h3><h3>bcd</h3>")) #>>['abd</h3><h3>bcd']
print(re.findall("<h3>.*</h3>","<h3>abd</h3><h3>bcd</h3>")) # ['<h3>abd</h3><h3>bcd</h3>']print(re.findall('\(.+\)', "A dog has(have a).这(哈哈)true()me"))
#>>['(have a).这(哈哈)true()']

量词的非贪婪(懒惰)模式, 在量词 +,*,?,{m,n} 后面加 '?' 则匹配尽可能短的字符串 。

# 在量词 +,*,?,{m,n} 后面加 '?' 则匹配尽可能短的字符串 。import re
m = "a.*?b"
for k in re.finditer(m,"aabab"):print(k.group(),end="\n") #>>aab ab
m = "<h3>.*?</h3>"
a = re.match(m,"<h3>abd</h3><h3>bcd</h3>")
print(a.group()) #>><h3>abd</h3>a = re.findall(m,"<h3>abd</h3><h3>bcd</h3>")
print(a) #>>['<h3>abd</h3>', '<h3>bcd</h3>']m = "<h3>.*?[M|K]</h3>"
a = re.match(m,"<h3>abd</h3><h3>bcK</h3>")
print(a.group()) #

匹配对象”(匹配成功时的返回结果)的属性

  • string: 匹配时使用的母串。
  • lastindex: 最后一个被匹配的分组的编号(不是最大编号)。如果没有被匹配的分组,将为None。
  • start([group]):返回指定的组匹配的子串在string中的起始位置。group默认值为0
  • end([group]):返回指定的组匹配的子串在string中的结束位置(子串最后一个字符的位置 +1)。group默认值为0。
  • span([group]):返回(start(group), end(group))。group可以是组编号,也可以是组名字,缺省为0

# 匹配对象”的函数m = re.match(r'(\w+) (\w+)(.)', 'hello world!ss')
print( m.string) #>>hello world!ss
print(m.lastindex) #>>3
print(m.group(0,1,2,3))#>>('hello world!', 'hello', 'world', '!')
print(m.groups()) #>>('hello', 'world', '!')
print(m.start(2)) #>>6
print(m.end(2)) #>>11
print(m.span(2)) #>>(6, 11)

诸葛亮口中的曹操

小说txt文本可以去此网站免费下载:

鬼吹灯_无弹窗书友最值得收藏的网络小说阅读网

# 诸葛亮口中的曹操import re
f = open("E:\jupyter_projects\python_projects\文本文件\三国演义.txt", "r", encoding="gbk")
txt = f.read()
# print(txt)f.close()
pt = "(孔明.{0,2}曰:“[^”]*(曹操|曹贼|操贼|曹阿瞒|操).*?”)"a = re.findall(pt, txt)
print(len(a)) #>>58
for x in a: #x形如: ('孔明答曰:“曹操乃汉贼也,又何必问?”', '操')print(x[0], end = '\n\n')

抽取ip地址、邮箱、网址

 

 

这篇关于郭炜老师mooc第九章正则表达式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/790937

相关文章

正则表达式高级应用与性能优化记录

《正则表达式高级应用与性能优化记录》本文介绍了正则表达式的高级应用和性能优化技巧,包括文本拆分、合并、XML/HTML解析、数据分析、以及性能优化方法,通过这些技巧,可以更高效地利用正则表达式进行复杂... 目录第6章:正则表达式的高级应用6.1 模式匹配与文本处理6.1.1 文本拆分6.1.2 文本合并6

JavaScript正则表达式六大利器:`test`、`exec`、`match`、`matchAll`、`search`与`replace`详解及对比

在JavaScript中,正则表达式(Regular Expression)是一种用于文本搜索、替换、匹配和验证的强大工具。本文将深入解析与正则表达式相关的几个主要执行方法:test、exec、match、matchAll、search和replace,并对它们进行对比,帮助开发者更好地理解这些方法的使用场景和差异。 正则表达式基础 在深入解析方法之前,先简要回顾一下正则表达式的基础知识。正则

匹配电子邮件地址的正则表达式

这个正则表达式 QRegularExpression regex(R"((\w+)(\.|_)?(\w+)@(\w+)(\.(\w+))+))"); 用于匹配电子邮件地址的格式。下面是对这个正则表达式的逐步解析和解释: 1. QRegularExpression 构造函数 QRegularExpression regex(R"((\w+)(\.|_)?(\w*)@(\w+)(\.(\w+))+

notepad++ 正则表达式多条件查找替换

基础语法参考: https://www.cnblogs.com/winstonet/p/10635043.html https://www.linuxidc.com/Linux/2019-05/158701.htm   通常情况下我们查找的内容和要被替换掉的内容是一样的,我们只需要使用正则表达式精确框定查找内容,替换直接输入要替换的内容即可。 但有时会比较复杂,查找的内容,只需要替换其中

js正则表达式test方法的问题

今天在网上碰到一个帖子,写了一个关于Regex的奇怪现象,(文章来源http://www.php100.com/html/webkaifa/javascript/2007/0109/1866.html) 代码如下 <script type="text/javascript"><!--var re = /^\d+(?:\.\d)?$/ig; alert(re.test('112.3'

Java利用正则表达式获取指定两个字符串之间的内容

package com.starit.analyse.util;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.List;import java.util.regex.Matcher;import java.util.regex.Pattern;public class DealSt

资料分析系统课-刘文超老师

1、考试大纲 2、解题的问题->解决方法     3、统计术语  基期量与现期量:作为对比参照的时期称为基期,而相对于基期的称为现期。描述具体数值时我们称之为基期量和现期量。 增长量:是指基期量与现期量增长(或减少)的绝对量。增长量是具体值,有单位。增长量=现期量-基期量。增长量有正负,负值代表减少量。增长率:  年均增长量:    年均增长率: 同比和环比

爬取豪ru老师刘艳小说

网址准备 可自行搜索,发现在电脑端无法获取内容,用浏览器仿手机的功能实现 抓包分析,发现网址非常简单,没有任何的反爬措施 可以得到返回的页面,而且字体也没用常见的反爬措施 接下来就分析各个章节的属性就大功告成了 爬取到了 警告,技术不可用于传播黄色

C语言-第九章:文件读写

传送门:C语言-第八章:指针进阶 目录 第零节:准备工作  第一节:文件的简单介绍         1-1.绝对路径与相对路径         1-2.文件的作用 第二节:文件操作         2-1.打开文件         2-2.关闭文件         2-3.读操作                 2-3-1.fgetc 读取一个字符

笔记 14 : 彭老师课本第 8 章, UART : 寄存器介绍 ,

(99) 继续介绍 uart 的关于通道的 一整套 寄存器, UCON 等: ++ 接着介绍寄存器 UTRSTAT : ++ 接着介绍读写数据的寄存器: ++ 设置 uart 的波特率,有关的寄存器: ++ (100) (101) 谢谢