《Python编程实训快速上手》第五天--模式匹配与正则表达式

news2024/11/23 13:15:35

一、不用正则表达式查找文本模式

文本模式是一种人为规定的结构,现在有一个模式:3个数字-3个数字-4个数字

使用isPhoneNumber()函数来判断字符串是否匹配该模式

def isPhoneNumber(number):
    if len(number) != 12:
        return False
    for i in range(0,3):
        if not number[i].isdecimal():
            return False
    if number[3] != "-":
        return False
    for i in range(4,7):
        if not number[i].isdecimal():
            return False
    if number[7] != "-":
        return False
    for i in range(8,12):
        if not number[i].isdecimal():
            return False

    return True

print(isPhoneNumber(""))
print(isPhoneNumber("112-564-7896"))
print(isPhoneNumber("112-7896-532"))

 

 上述代码缺陷在于它仅能处理一种模式,新增一个模式后,就要增加新的代码

如果想在更长的字符串中寻找电话号码,就必须添加更多代码来寻找电话号码模式:

message = "Call me at 415-555-1011 tomorrow, 415-555-9865 is my office"
for i in range(len(message)):
    chunk = message[i:i+12]
    if isPhoneNumber(chunk):
        print("Phone number %s is found"%chunk)
print("done")

 

总结上述代码发现,如果在一个长度为百万的字符串中匹配模式,那么效率是十分低下的 

 二、使用正则表达式查找文本模式

1、创建正则表达式对象

1)正则表达式的函数均在re模块中,导入即可:import re

2)创建Regex模式对象:phoneNumRegex = re.compile(r"\d\d\d-\d\d\d-\d\d\d\d")

\d在正则表达式中表示一位数字字符,即0~9的数字 

2、匹配Regex对象

整体代码如下:

import re
phoneNumRegex = re.compile(r"\d{3}-\d{3}-\d{4}")
mo = phoneNumRegex.search("My number is 123-456-7890")
print("My phone number is found: " + mo.group())

首先,对象使用search方法查找传入的字符串,寻找正则表达式的所有匹配。如果未找到正则表达式模式,则返回None。如果找到了,则返回一个Match对象,使用Match对象中的group()方法,返回查找字符串中实际匹配的文本 

3、正则表达式过程匹配回顾

  1. import re
  2. re.compile()函数创建Regex对象
  3. 使用search()方法 返回Match对象
  4. 使用group()方法返回实际匹配文本的字符串

三、用正则表达式匹配更多模式

1、利用()分组

现在想将\d\d\d-\d\d\d-\d\d\d\d分成两组即\d\d\d和\d\d\d-\d\d\d\d,做法是(\d\d\d)-(\d\d\d-\d\d\d\d)

上边提到使用group()方法进行匹配字符串返回 ,因此操作如下:

mo.group()---->"123-456-7890"

mo.group(0)---->"123-456-7890"

mo.group(1)---->"123"

mo.group(2)---->"456-7890"

mo.groups()---->("123","456-7890")

group中的数字表示第几个分组

前边使用compile()方法时曾使用r进行原始字符串的转换, 从而消除\d中\的转义作用。

在正则表达式中,也存在一些特殊字符:.  ^  $  *  +  ?  {  }  [  ]  \  |  (  )

如果模式中刚好出现上述特殊字符,则需要用\进行转义操作,例如:r"(\(\d\))"

2、用管道匹配多个分组

字符 | 表示管道,r"a|b"表示匹配"a" 或"b",即若先遇到a,则返回a;先遇到b,则返回b

batRegex = re.compile(r"Batman|computer")
mo = batRegex.search("Batman has a computer")
print(mo.group())
mo = batRegex.search("A computer was bought by Batman")
print(mo.group())

也可匹配多个模式中的一个,允许提取公共项方式,假设希望匹配Batman、Batmobile、Batcopter和Batbar中的任意一个,则代码如下

batRegex = re.compile(r"Bat(man|mobile|copter|bar)")
mo = batRegex.search("Batman is rich")
print(mo.group())
print(mo.group(1))

 

3、用?实现可选择匹配

字符?表明它前边的分组在这个模式中是可选的,即无论这段文本在不在,正则表达式都会认为匹配。利用前边电话例子,寻找包含区号或不包含区号的电话号码:

phoneNumRegex = re.compile(r"(\d{3}-)?\d{3}-\d{4}")
mo = phoneNumRegex.search("My number is 123-456-7890")
print("My phone number is found: " + mo.group())
mo = phoneNumRegex.search("My number is 456-7890")
print("My phone number is found: " + mo.group())

4、用*匹配0次或多次

 *前的分组可以在文本中出现任意次(包括0次)

phoneNumRegex = re.compile(r"(\d{3}-)*\d{3}-\d{4}")
mo = phoneNumRegex.search("My number is 456-7890")
print("My phone number is found: " + mo.group())
mo = phoneNumRegex.search("My number is 123-456-7890")
print("My phone number is found: " + mo.group())
mo = phoneNumRegex.search("My number is 123-456-223-7890")
print("My phone number is found: " + mo.group())

 

 5、用+匹配1次或多次

+前的分组必须“至少出现1次” 

phoneNumRegex = re.compile(r"(\d{3}-)+\d{3}-\d{4}")
mo = phoneNumRegex.search("My number is 456-7890")
if mo is None:
    print("My phone number is not found")
mo = phoneNumRegex.search("My number is 123-456-7890")
print("My phone number is found: " + mo.group())
mo = phoneNumRegex.search("My number is 123-456-223-7890")
print("My phone number is found: " + mo.group())

 

 6、用{}匹配特定次数

\d{3}表示让\d重复3次,即\d\d\d

1)指定循环次数:将一个分组重复特定次数,就在该分组后跟上{数字}

2)指定范围:

(ha){1,3}将匹配"ha"、"haha"、"hahaha"

(ha){1,}表示不限定最大值

(ha){,5}表示匹配0~5次

四、贪心和非贪心匹配

Python的正则表达式默认是“贪心的”,在有二义性的情况下,会尽可能匹配最长的字符串,例如(ha){1,3}去查找"hahaha"时只会返回"hahaha"。

{}?表示“非贪心”版本,即会尽可能匹配最短的字符串

greedyRegex = re.compile(r"(Ha){3,5}")
mo1 = greedyRegex.search("HaHaHaHaHa")
print(mo1.group())

unGreedyRegex = re.compile(r"(Ha){3,5}?")
mo2 = unGreedyRegex.search("HaHaHaHaHa")
print(mo2.group())

 

五、findall()方法

search()方法只返回一个match对象,包含被查找字符串中的“第一次”匹配的文本

findall()方法将返回一组字符串列表, 包含被查找字符串中的“所有”匹配的文本

findall()方法返回结果总结:

  1. 没有分组,将返回一个匹配字符串的列表
  2. 有分组,返回一个字符串的元组的列表,每个分组对应一个字符串 

1)没有分组: 

phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')
print(phoneNumRegex.findall("Cell: 415-856-7854 work:235-000-7459"))

 

2)有分组

phoneNumRegex = re.compile(r'(\d\d\d)-(\d\d\d)-(\d\d\d\d)')
print(phoneNumRegex.findall("Cell: 415-856-7854 work:235-000-7459"))

 

六、字符分类

常见字符分类缩写代码
\d0~9的任意数字
\D除0~9数字外的任何字符
\w任何字母、数字或下划线字符(匹配“单词”字符)
\W除字母、数字和下划线以外的任何字符
\s空格、制表符或换行符(匹配“空白”字符)
\S除空格、制表符或换行符外的任何字符

 \d+\s\w+表示匹配的文本有一个或多个数字( \d+),然后是一个空白字符(\s),接下来是一个或多个字母/数字/下划线字符(\w+)

七、建立自己的字符分类

使用[]定义自己的字符分类,在[]内普通的正则表达式符号不会被解释,因此无需加\进行转义

在做方括号后加上一个^字符,即可得到“非字符类”,即不在这个字符类中的所有字符

phoneNumRegex = re.compile(r'[aeiouAEIOU]')
print(phoneNumRegex.findall("Bittersweet as life is, It's still wonderful, and It's fascinating even in tragedy"))
phoneNumRegex = re.compile(r'[^aeiouAEIOU]')
print(phoneNumRegex.findall("Bittersweet as life is, It's still wonderful, and It's fascinating even in tragedy"))

八、插入字符和美元符号

在正则表达式开始处使用^符号,表示匹配必须发生在被查找文本开始处

在正则表达式末尾使用$符号,表示该字符串必须以这个正则表达式的模式结束

同时使用^和$符号,表示整个字符串必须匹配该模式

如果字符串违背上述规定,则查找结果返回None

未完待续………

 

 

 

 

 

 

 

 

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

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

相关文章

文件读写函数(1)

大家好,今天我们来介绍一下文件读写函数,昨天我们已经简单提及了一下文件的概念,那么我们今天就不多说,下面我们来看函数。 1.fopen函数 这个函数是用来打开文件的,它的两个参数分别是文件名和文件的打开模式&#x…

华为数通HCIA系列第5次考试-【2024-46周-周一】

文章目录 1、子网掩码有什么作用,和IP地址是什么关系,利用子网掩码可以获取哪些信息?2、已知一个IP地址是192.168.1.1,子网掩码是255.255.255.0,求其网络地址3、已知某主机的IP地址是192.168.100.200,子网掩…

Linux(CentOS)运行 jar 包

1、在本地终端运行,关闭终端,程序就会终止 java -jar tlias-0.0.1-SNAPSHOT.jar 发送请求,成功 关闭终端(程序也会终止) 发送请求,失败 2、在远程终端运行,关闭终端,程序就会终止 …

GIT:如何查找已删除的文件的历史记录

首先你得知道文件的名称和路径 然后打开 gitlab,到项目中,仓库-> 文件 查找文件 复制文件名到可能存在过这个文件的分支当中,就能看到了

C++builder中的人工智能(21):Barabási–Albert model(BA)模型

在此之前,大多数网络被想当然的认为是随机的,因此连接度分布可以近似用泊松分布来表示,而巴拉巴西与其学生阿尔伯特、郑浩雄通过对万维网度分布测量的结果却显示万维网度分布服从幂律分布,存在枢纽节点(拥有大量链接的…

新手 Vue 项目运行

前言:前面讲了我们已经将spingboot项目运行起来了,现在我们只需将后台管理的Vue项目运行起来即可完成整个项目。 在运行vue项目之前,请先运行springboot项目,运行步骤请看:运行Springboot Vue 项目_springbootvue项目…

AUTOSAR_EXP_ARAComAPI的7章笔记(2)

☞返回总目录 相关总结:服务发现实现策略总结 7.2 服务发现的实现策略 如前面章节所述,ara::com 期望产品供应商实现服务发现的功能。服务发现功能基本上是在 API 级别通过 FindService、OfferService 和 StopOfferService 方法定义的,协议…

计算机网络分析题

网络的布置 根据具体需求布置网络 第二小题、网络的划分 根据路由表作出路由器拓扑图 ARP跨网络寻址 TCP报文段格式概念 网桥的转发表与动作 网络嗅探报文 十六进制化作十进制 嗅探以太网帧首部 除MAC帧以外,其他各层协议数据单元都是源地址在前,目…

【初阶数据结构与算法】线性表之链表的分类以及双链表的定义与实现

文章目录 一、链表的分类二、双链表的实现1.双链表结构的定义2.双链表的初始化和销毁初始化函数1初始化函数2销毁函数 3.双链表的打印以及节点的申请打印函数节点的申请 4.双链表的头插和尾插头插函数尾插函数 5.双链表的查找和判空查找函数判空函数 6.双链表的头删和尾删头删函…

【AI写作宝-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 1. 暴力破解密码,造成用户信息泄露 2. 短信盗刷的安全问题,影响业务及导致用户投诉 3. 带来经济损失,尤其是后付费客户,风险巨大,造…

【HarmonyNext】显示提示文字的方法

【HarmonyNext】显示提示文字的方法 本文介绍在 HarmonyNext 中显示提示文字的两种常见方法:使用自定义弹窗 CustomDialog 和使用 promptAction 的 showToast 方法。 一、使用自定义弹窗 CustomDialog 在 HarmonyNext 中,自定义弹窗是实现复杂提示信…

【3D Slicer】的小白入门使用指南

一、3D Slicer认识 3D Slicer是一个开源医学影像分析和可视化平台(本质是TotalSegmentator的软件版)。(补充:TotalSegmentator 是一个用于医学图像分割的开源工具,能够对104种解剖结构进行精确分割。该项目基于深度学习技术,支持CT和MR图像的处理。TotalSegmentator 提供…

ts定义接口返回写法

接口&#xff08;未进行ts定义&#xff09; export async function UserList(params: {// keyword?: string;current?: number;pageSize?: number;},// options?: { [key: string]: any }, ) {return request<API1.UserList>(http://geek.itheima.net/v1_0/mp/artic…

.NET Core 应用程序如何在 Linux 中创建 Systemd 服务 ?

.NET Core 和 Linux 已经成为一个强大的组合&#xff0c;为开发人员提供了一个灵活、高性能的平台来构建和运行应用程序。在 Linux 上部署 .NET Core 应用程序的一个关键方面是利用 systemd 服务来确保应用程序顺利运行&#xff0c;在开机时自动启动&#xff0c;并在失败后重新…

低代码平台总览

低代码平台&#xff08;Low-Code Platform&#xff09;是一种软件开发工具&#xff0c;它允许用户通过图形化界面和少量的编码来快速构建应用程序。低代码平台的核心理念是通过抽象和最小化手工编码的方式&#xff0c;加速软件开发和部署的过程。以下是低代码平台的一些关键特性…

分布式----Ceph部署(上)

目录 一、存储基础 1.1 单机存储设备 1.2 单机存储的问题 1.3 商业存储解决方案 1.4 分布式存储&#xff08;软件定义的存储 SDS&#xff09; 1.5 分布式存储的类型 二、Ceph 简介 三、Ceph 优势 四、Ceph 架构 五、Ceph 核心组件 #Pool中数据保存方式支持两种类型&…

华为诺亚方舟新作:GUI Agent综述

1、摘要 智能代理可以做更复杂的任务。特别是模拟人类在GUI上进行交互&#xff0c;比如点击和打字。 本论文对此进行总结&#xff0c;特别是其中最关键的数据、框架和应用。 首先是数据集和基准。 其次是统一框架&#xff0c;涵盖了关键组件和分类体系。 此外是基于MLLM的GUI…

(65)使用RLS自适应滤波器进行信道均衡的MATLAB仿真

文章目录 前言一、仿真说明二、码间串扰、色散、与频率选择性衰落1. 码间串扰&#xff08;ISI&#xff09;2. 信道的色散与码间串扰3. 减少ISI的方法 三、MATLAB仿真代码四、仿真结果1.发送16QAM信号的星座图2.信道的频率响应3.接收16QAM信号的星座图4.均衡后16QAM信号的星座图…

数据结构与算法:双指针之“最长连续不重复子序列” +位运算之“求二进制中第k个数字”、“求二进制表示”、“二进制中1的个数” +整数离散化

双指针&#xff1a; 简介 常见问题分类&#xff1a; 对于一个序列&#xff0c;用两个指针维护某一段特定的区间 对于两个序列&#xff0c;维护某种次序&#xff08;譬如归并排序中合并两个有序序列的操作&#xff09; 双指针算法的最核心点在于&#xff0c;将O(N^2)的暴力…

东方通TongWeb替换Tomcat的踩坑记录

一、背景 由于信创需要&#xff0c;原来项目的用到的一些中间件、软件都要逐步替换为国产品牌&#xff0c;决定先从web容器入手&#xff0c;将Tomcat替换掉。在网上搜了一些资料&#xff0c;结合项目当前情况&#xff0c;考虑在金蝶AAS和东方通TongWeb里面选择&#xff0c;后又…