挑战30天学完Python:Day18 正则表达式

📘 Day 18

🎉 本系列为Python基础学习,原稿来源于 30-Days-Of-Python 英文项目,大奇主要是对其本地化翻译、逐条验证和补充,想通过30天完成正儿八经的系统化实践。此系列适合零基础同学,或仅了解Python一点知识,但又没有系统学习的使用者。总之如果你想提升自己的Python技能,欢迎加入《挑战30天学完Python》

  • 📘 Day 18
    • 正则表达式
      • re 模块
      • re 函数
        • match
        • search
        • findall
        • sub
        • split
    • 正则语法
      • 方括号 []
      • 转义 \
      • 一或多次 +
      • 任意字符 .
      • 零或多次 *
      • 零或一次 ?)
      • 数量 {}
      • 开头 ^
      • 不包含 [^]
    • 💻 第18天练习
      • 练习1级
      • 练习2级
      • 练习3级

正则表达式

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。要在python中使用RegEx,首先我们应该导入名为 re 的模块。

re 模块

导入模块以后,我们就可以使用它来检查或者查找了。

import re

re 函数

为了使用不同的模式进行查找, re 提供了一些函数方法来进行匹配。

  • re.match: 只在字符串的第一行开始搜索,如果找到则返回匹配的对象,否则返回None。
  • re.search: 如果字符串(包括多行字符串)中有匹配对象,则返回匹配对象。
  • re.findall: 返回包含所有匹配项的列表,如果没有匹配则返回空列表。
  • re.split: 方法按照能够匹配的子串将字符串分割后返回列表。
  • re.sub: 查找并替换一个或者多个匹配项。
Match
# 语法形式
match(pattern, string, flags=0)
# pattern: 匹配的正则表达式
# string:要匹配的字符串
# flags:[可选] 用来控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等
import retxt = 'I love to teach python and javaScript'
# 本身反馈一个 span 对象
match = re.match('I love to teach', txt, re.I)  # re.I 不区分大小写
print(match)  # <re.Match object; span=(0, 15), match='I love to teach'># 进一步我们可以使用span()获取匹配的起始位置和结束位置的元组值
span = match.span()
print(span)     # (0, 15)# 再进一步可以打印出拆分的起始和结束索引,以及使用分片获取匹配字符串
start, end = span
print(start, end)  # 0, 15
substring = txt[start:end]
print(substring)       # I love to teach

如例上边例子中示,我们在目标字符串中查找是否有 I love to teach 的字符串匹配。其中从开始的位置我们找到了对应匹配,进而得到了一个对象的返回。

import retxt = 'I love to teach python and javaScript'
match1 = re.match('I like to teach', txt, re.I)
print(match1)  # Nonematch2 = re.match('love', txt)
print(match2)  # None

此例子中字符串不包含 I like to teach,或者没用匹配开头字符,因此匹配方法返回None。

Search
# 语法
re.search(pattern, string, flags=0)
# 参数说明同match
import retxt = '''Python is the most beautiful language that a human being has ever created.
I recommend python for a first programming language'''# 返回匹配对象span
match = re.search('first', txt, re.I)
print(match)  # <re.Match object; span=(100, 105), match='first'># 获取匹配开始和结束位置元组
span = match.span()
print(span)     # (100, 105)# 获取开始和结束值,并获截取字字符串
start, end = span
print(start, end)  # 100 105
substring = txt[start:end]
print(substring)       # first# 没有任何匹配返回None
nom = re.search('weather', txt, re.I)
print(nom)  # None

正如你所见,搜索要比匹配方式好的多。因为它可以在整个文本中进行查找匹配。并返回第一找到的对象,否则返回None。接下来还有一个更好的函数 findall 它可以匹配所有并以列表形式返回。

findall

findall() 以列表的形式返回所有匹配

import retxt = '''Python is the most beautiful language that a human being has ever created.
I recommend python for a first programming language'''matches = re.findall('language', txt, re.I)
print(matches)  # ['language', 'language']

可以看到,单词 language 在字符串中出现了两次。现在我们将在字符串中寻找Python和Python单词:

txt = '''Python is the most beautiful language that a human being has ever created.
I recommend python for a first programming language'''# It returns list
matches = re.findall('python', txt, re.I)
print(matches)  # ['Python', 'python']

这个例子中因为我们使用标记位(re.I) 忽略大小写,所以返回两个。如果我们没有使用它,看看是什么结果。

import re
matches = re.findall('Python', txt)
print(matches)  # ['Python']

当然我们如果想要达到其他效果,也可以用其他方法,不过就没有上边使用标记位那么优雅了。

import re
txt = '''Python is the most beautiful language that a human being has ever created.
I recommend python for a first programming language'''matches = re.findall('Python|python', txt)
print(matches)  # ['Python', 'python']#
matches = re.findall('[Pp]ython', txt)
print(matches)  # ['Python', 'python']
sub

匹配并替换字符串,直接看例子:

import re
txt = '''Python is the most beautiful language that a human being has ever created.
I recommend python for a first programming language'''match_replaced = re.sub('Python|python', 'JavaScript', txt, re.I)
print(match_replaced)  # JavaScript is the most beautiful language that a human being has ever created.# 或者
match_replaced = re.sub('[Pp]ython', 'JavaScript', txt, re.I)
print(match_replaced)  # JavaScript is the most beautiful language that a human being has ever created.

让我们再来看一个例子。下边是一个包含很多多余 % 字符的字符串,让人晦涩难懂。让我们用此方法清楚掉它。

import re
txt = '''%I a%m te%%a%%che%r% a%n%d %% I l%o%ve te%ach%ing. 
T%he%re i%s n%o%th%ing as r%ewarding a%s e%duc%at%i%ng a%n%d e%m%p%ow%er%ing p%e%o%ple.
I fo%und te%a%ching m%ore i%n%t%er%%es%ting t%h%an any other %jobs. 
D%o%es thi%s m%ot%iv%a%te %y%o%u to b%e a t%e%a%cher?'''matches = re.sub('%', '', txt)
print(matches)

得到整洁的文本输出

I am teacher and  I love teaching. 
There is nothing as rewarding as educating and empowering people.
I found teaching more interesting than any other jobs.
Does this motivate you to be a teacher?
split

返回分割后的列表。

txt = '''I am teacher and  I love teaching.
There is nothing as rewarding as educating and empowering people.
I found teaching more interesting than any other jobs.
Does this motivate you to be a teacher?'''
print(re.split('\n', txt)) # 按照换行符 \n 进行分割返回# 其实等同于字符直接调用split方法
print(txt.split('\n'))  
['I am teacher and  I love teaching.', 'There is nothing as rewarding as educating and empowering people.', 'I found teaching more interesting than any other jobs.', 'Does this motivate you to be a teacher?']

正则语法

在以往我们声明一个变量,使用的是单引号或者双引号。如果要声明一个正则变量则是 r''
下面的模式仅用小写字母标识apple,为了使其不区分大小写,我们要么重写模式,要么添加一个标志。

import reregex_pattern = r'apple'
txt = 'Apple and banana are fruits. An old cliche says an apple a day a doctor way has been replaced by a banana a day keeps the doctor far far away. '
matches = re.findall(regex_pattern, txt)
print(matches)  # ['apple']# 添加标记位使其大小写不敏感
matches = re.findall(regex_pattern, txt, re.I)
print(matches)  # ['Apple', 'apple']# 或者我们使用一组规则匹配方法
regex_pattern = r'[Aa]pple'  # [Aa]表示匹配字符串首字符可以是大写A,也可以是小写a
matches = re.findall(regex_pattern, txt)
print(matches)  # ['Apple', 'apple']

这里先附上标记位包含哪些:

  • re.I:匹配对大小写不敏感
  • re.M:多行匹配(影响 ^ 和 $)
  • re.S:使 . 匹配包括换行在内的所有字符

然后就详细看下正则里的一些语法符

  • []: 一组字符
    • [a-c] 表示 a 或 b 或 c
    • [a-z] 表示 小写 a 到 z 任意字符
    • [A-Z] 表示 大写 A to Z 任意字符
    • [0-3] 表示 0 或 1 或 2 或 3
    • [0-9] 表示0 到 9 任意数字
    • [A-Za-z0-9] 表示任意单字符, 即 小写字母a到z, 大写字母A到Z 或数字0到9
  • \: 转义特殊字符
    • \d 表示 匹配任意数字,相当于 [0-9].
    • \D 表示 匹配任意非数字
  • . : 匹配任意字符(除了换行符 \n)
  • ^: 匹配开头
    • r’^substring’ 例如 r’^love’, 必须以love开头的句子
    • r’[^] 表示不在[]中的字符,例如 r’[^abc] 表示不是a, 不是b, 不是c。即除a,b,c之外的字符
  • $: 匹配结尾
    • r’substring ′ 举例 r ′ l o v e ' 举例 r'love 举例rlove’, 必须以love结尾的句子
  • *: 0或多个次
    • r’[a]*’ 表示可以不出现,或者可以出现多次
  • +: 0或多个次
    • r’[a]+’ 表示至少一次或多次
  • ?: 0或1次
    • r’[a]?’ 表示零次或一次
  • {n}:精确匹配个数
    • {3}: 表示 正好3个字符
    • {3,}: 表示 至少3个字符
    • {3,8}: 表示 3到8个字符
  • |: 不是就是(或)
    • r’apple|banana’ 表示要么是 apple 要么是 banana
  • (): 正则表达式分组并记住匹配的文本

在这里插入图片描述

让我们用一些例子来上边这些匹配字符是如何使用的。

方括号 []

让我们用方括号来匹配小写和大写

import reregex_pattern = r'[Aa]pple'
txt = 'Apple and banana are fruits. An old cliche says an apple a day a doctor way has been replaced by a banana a day keeps the doctor far far away.'
matches = re.findall(regex_pattern, txt)
print(matches)  # ['Apple', 'apple']

如我我们想再额外查找 banana,我们可以优化匹配如下:

import reregex_pattern = r'[Aa]pple|[Bb]anana' 
txt = 'Apple and banana are fruits. An old cliche says an apple a day a doctor way has been replaced by a banana a day keeps the doctor far far away.'
matches = re.findall(regex_pattern, txt)
print(matches)  # ['Apple', 'banana', 'apple', 'banana']

我们在方括号中使用了字符或 | ,因此设法提取出了 Apple, Apple, Banana 和 Banana。

转义 \

import reregex_pattern = r'\d'  # 
txt = 'This regular expression example was made on December 6,  2019 and revised on July 8, 2021'
matches = re.findall(regex_pattern, txt)
print(matches)  # ['6', '2', '0', '1', '9', '8', '2', '0', '2', '1'], 提取了所有数字,但这却不是我们想要的效果

一或多次 +

结合上边 \d 使用+做个组合优化

import reregex_pattern = r'\d+'  # d表示匹配数字, +表示一次或多次
txt = 'This regular expression example was made on December 6,  2019 and revised on July 8, 2021'
matches = re.findall(regex_pattern, txt)
print(matches)  # ['6', '2019', '8', '2021'] - 现在才是我们想要的效果

任意字符 .

import reregex_pattern = r'[a].'  # 小写a和任意
txt = '''Apple and banana are fruits'''
matches = re.findall(regex_pattern, txt)  # 匹配多个项目
print(matches)  # ['an', 'an', 'an', 'a ', 'ar'] 分别对应and中an,banana中an、an、a空格,are中ar regex_pattern = r'[a].+'  # . 任意字符, + 一次或多次(连续)
matches = re.findall(regex_pattern, txt)
print(matches)  # ['and banana are fruits']

零或多次 *

零次或多次。即可能不会出现,也可能多次出现。

import reregex_pattern = r'[a].*'
txt = '''Apple and banana are fruits'''
matches = re.findall(regex_pattern, txt)
print(matches)  # ['and banana are fruits']

零或一次 ?

零次或一次。即可能不会出现,也可能只出现一次。

import retxt = '''I am not sure if there is a convention how to write the word e-mail.
Some people write it as email others may write it as Email or E-mail.'''
regex_pattern = r'[Ee]-?mail'  # ? 表示 - 是个可选项
matches = re.findall(regex_pattern, txt)
print(matches)  # ['e-mail', 'email', 'Email', 'E-mail']

正则数量 {}

我们可以使用花括号指定我们在文本中寻找的子字符串的长度。让我们想一下,我们如果对一个长度为4个字符的子字符串感兴趣的话:

import retxt = '今年的大年三十日期是2023年1月23日,去年的则是2022年1月31日,真是一年比一年早'
regex_pattern = r'\d{4}'  # 精准匹配有四个数字的
matches = re.findall(regex_pattern, txt)
print(matches)  # ['2023', '2022']regex_pattern = r'\d{1,4}'   # 匹配1,2,3,4 贪婪模式
matches = re.findall(regex_pattern, txt)
print(matches)  # ['2023', '1', '23', '2022', '1', '31']

开头 ^

  • 匹配字符串的开头
import retxt = '今天天气很好,所以今天你的心情好吗?'
regex_pattern = r'^今天'  # ^ 表示必须以“今天”开头
matches = re.findall(regex_pattern, txt)
print(matches)  # ['今天'] 注意只返回了一个

不包含 [^]

import retxt = '今年的大年三十日期是2023年1月23日,去年的则是2022年1月31日,真是一年比一年早'
regex_pattern = r'[^\u4e00-\u9fa5, ]+'  # ^ 排除中文字符,逗号和空格
matches = re.findall(regex_pattern, txt)
print(matches)  # ['2023', '1', '23', '2022', '1', '31']

💻 第18天练习

练习1级

  1. 下面这段话中出现频率最高的单词是什么?
    paragraph = 'I love teaching. If you do not love teaching what else can you love. I love Python if you do not love something which can give you all the capabilities to develop an application what else can you love.
    [(6, 'love'),(5, 'you'),(3, 'can'),(2, 'what'),(2, 'teaching'),(2, 'not'),(2, 'else'),(2, 'do'),(2, 'I'),(1, 'which'),(1, 'to'),(1, 'the'),(1, 'something'),(1, 'if'),(1, 'give'),(1, 'develop'),(1, 'capabilities'),(1, 'application'),(1, 'an'),(1, 'all'),(1, 'Python'),(1, 'If')]
  1. 从以下这段对话中提取数字 “The position of some particles on the horizontal x-axis are -12, -4, -3 and -1 in the negative direction, 0 at origin, 4 and 8 in the positive direction.” 并计算出最远距离点。
points= ['-12', '-4', '-3', '-1', '0', '4', '8']
sorted_points= [-12, -4, -3, -1, 0, 4, 8]
distance = |-12| + |8|  # 20

练习2级

  1. 编写一个方法来识别字符串是否是有效的python变量
    is_valid_variable('first_name') # True
    is_valid_variable('first-name') # False
    is_valid_variable('1first_name') # False
    is_valid_variable('firstname') # True
    

练习3级

  1. 清除以下文本无用的字符。且统计出优化后的文本中出现频率最高的三个单词。

    sentence = '''%I $am@% a %tea@cher%, &and& I lo%#ve %tea@ching%;. There $is nothing; &as& mo@re rewarding as educa@ting &and& @emp%o@wering peo@ple. ;I found tea@ching m%o@re interesting tha@n any other %jo@bs. %Do@es thi%s mo@tivate yo@u to be a tea@cher!?'''print(clean_text(sentence))
    I am a teacher and I love teaching There is nothing as more rewarding as educating and empowering people I found teaching more interesting than any other jobs Does this motivate you to be a teacher
    print(most_frequent_words(cleaned_text)) # [(3, 'I'), (2, 'teaching'), (2, 'teacher')]
    

练习参考答案请移步 github项目地址 18_exercise.py

<< Day 17 | Day 19 >>

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

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

相关文章

测试开源C#人脸识别模块DlibDotNet

百度“C# 换脸”找到参考文献4&#xff0c;发现其中使用DlibDotNet检测并识别人脸&#xff08;之前主要用的是ViewFaceCore&#xff09;&#xff0c;DlibDotNet是Dlib的.net封装版本&#xff0c;后者为开源C工具包&#xff0c;支持机器学习算法、图像处理等算法以支撑各类高级应…

CVE-2023-44313 Apache ServiceComb Service-Center SSRF 漏洞研究

本次项目基于go语言&#xff08;本人不精通&#xff09;&#xff0c;虽不是java web框架了 &#xff0c;但搭建web服务的框架一些思想理念却是通用的&#xff0c;我们由此可以得到一些蛛丝马迹....... 目录 漏洞简介 漏洞分析 漏洞复现 漏洞简介 Apache ServiceComb Servi…

应用感知型网络性能管理

网络基础设施似乎日益复杂和先进&#xff0c;迫使网络管理员抛弃传统的管理方法。应用感知型网络性能管理是一种用于监控网络性能的新型整体方法&#xff0c;它为管理员提供了强大的 IT 资源管理功能。应用感知型网络性能管理为 IT 管理员带来了精细视图、动态资源分配、主动故…

【计网】TCP的三次握手四次挥手

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;JAVA ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 三次握手&#xff08;Connection Establishment&#xff09; 四次挥手&#xff08;Connection Termination&#xff09; 结语 我…

Linux之权限管理

目录 一.chmod 二.ACL权限 2.1概述 2.2应用ACL权限 一.chmod chmod命令是控制用户对文件的权限的命令。 只有文件所有者和超级用户可以修改文件或目录的权限。 使用权限 : 所有使用者 语法: chmod [-cfvR] [--help] [--version] mode file... 参数说明&#xff1a; mode : …

前端学习——vue学习

文章目录 1. < el-form> 属性 model、prop、rules2. v-bind 与 v-model3. v-if 与 v-show4. v-for 循环语句5. 计算属性 computed6. 监视属性 watch7. 下拉框 el-select、el-option8. 自定义事件9. async与await实现异步调用 1. < el-form> 属性 model、prop、rule…

Elasticsearch:基于 Langchain 的 Elasticsearch Agent 对文档的搜索

在今天的文章中&#xff0c;我们将重点介绍如何使用 LangChain 提供的基础设施在 Python 中构建 Elasticsearch agent。 该 agent 应允许用户以自然语言询问有关 Elasticsearch 集群中数据的问题。 Elasticsearch 是一个强大的搜索引擎&#xff0c;支持词法和向量搜索。 Elast…

项目管理:如何成功完成一个项目

项目管理是一项重要的技能&#xff0c;它可以帮助你成功地完成一个项目。以下是一些关键的步骤&#xff0c;可以帮助你实现这一目标&#xff1a; 1. 明确项目目标&#xff1a;在开始项目之前&#xff0c;你需要明确项目的目标。这将有助于你制定一个明确的计划&#xff0c;并确…

HDFS 之 Topology(Rack) Awareness - 机架感知

1、 简介 机架感知在大型分布式存储系统中非常实用,可以有效保证数据的高可用,同时提升集群稳定性。在HDFS中,也实现了类似Topology Awareness的机制,只不过是采用软件的方式模拟。 2、机架感知存在的意义 分布式存储系统的一个特殊之处在于其通常包含非常多的机器。Clie…

【目标航迹管理(1)】基于d-s证据理论信息融合的多核目标跟踪方法

1 引言&#xff1a;从航机起始方法开始 我们为什么会有这个议题&#xff1f;因为航机起始方法。 处理目标航迹起始的方法主要分为两大类&#xff1a;批处理和序贯。 在杂波密度比较高的环境下&#xff0c;比如有红外卫星或地面雷达监视区域&#xff0c;则选用批处理方法&…

【Spring】SpringBoot 单元测试

目 录 一.什么是单元测试&#xff1f;二.单元测试有哪些好处&#xff1f;三.Spring Boot 单元测试使用单元测试的实现步骤 一.什么是单元测试&#xff1f; 单元测试&#xff08;unit testing&#xff09;&#xff0c;是指对软件中的最小可测试单元进行检查和验证的过程就叫单元…

Vue监听器(上)之组合式watch

1. 定义监听器 //要监视的属性被改变时触发 watch(要监视的属性, (更改后的心值, 更改前的旧值) > {具体操作}, );//监视对象为getter的时候 //表达式内任意响应式属性被改变时触发 watch(() > return表达式, (表达式的新值, 表达式的旧值) > {具体操作} );//数组中任…

【MySQL】多表操作、事务、索引

MySQL MYSQL 多表设计 一对多插入测试数据外键约束(物理外键)使用逻辑外键 MYSQL 多表设计 一对一表结构 MYSQL 多表设计 多对多 MYSQL 多表设计 一对多 建表语句 员工表 CREATE TABLE tb_emp (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT ID,username VARCHAR(20) N…

图片大了怎么缩小上传?30秒解决图片大小问题

在上传图片到网站、社交媒体、电子邮件或其他在线平台时&#xff0c;压缩图片可以减小文件大小&#xff0c;加快上传速度&#xff0c;并节省带宽和存储空间&#xff0c;许多网站和应用程序都有对上传图片大小的限制&#xff0c;因此利用在线图片压缩工具&#xff08;https://ww…

WordPres Bricks Builder 前台RCE漏洞

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

Jetpack Compose 架构层

点击查看&#xff1a;Jetpack Compose 架构层 官网 本页面简要介绍了组成 Jetpack Compose 的架构层&#xff0c;以及这种设计所依据的核心原则。 Jetpack Compose 不是一个单体式项目&#xff1b;它由一些模块构建而成&#xff0c;这些模块组合在一起&#xff0c;构成了一个完…

VSCODE include错误 找不到 stdio.h

解决办法&#xff1a; Ctrl Shift P 打开命令面板&#xff0c; 键入 “Select Intellisense Configuration”&#xff08;下图是因为我在写文章之前已经用过这个命令&#xff0c;所以这个历史记录出现在了第一行&#xff09; 再选择“Use gcc.exe ”&#xff08;后面的Foun…

C语言-数组指针与指针数组

一、简介 对于使用C语言开发的人来说&#xff0c;指针&#xff0c;大家都是非常熟悉的。数组&#xff0c;大家也同样熟悉。但是这两个组合到一起的话&#xff0c;很多人就开始蒙圈了。这篇文章&#xff0c;就详细的介绍一下这两个概念。 指针数组和数组指针&#xff0c;听起来非…

PyTorch概述(二)---MNIST

NIST Special Database3 具体指的是一个更大的特殊数据库3&#xff1b;该数据库的内容为手写数字黑白图片&#xff1b;该数据库由美国人口普查局的雇员手写 NIST Special Database1 特殊数据库1&#xff1b;该数据库的内容为手写数字黑白图片&#xff1b;该数据库的图片由高…

互联网广告投放与IP地理位置定位

随着互联网的发展和普及&#xff0c;互联网广告投放成为各行业推广营销的重要方式之一。而结合IP地理位置定位技术&#xff0c;可以实现精准定向&#xff0c;提高广告投放的效果和精准度。IP数据云将探讨互联网广告投放与IP地理位置定位的关系&#xff0c;分析其优势和应用场景…