Python(13)正则表达式简述

简介: Python(13)正则表达式简述

一、概述


  • 字符串是编程时用到的最多的一种数据类型,在工作中需要对字符串进行操作的场景无处不在,例如:


判断一个字符串是否是合法的Email地址


上面的需求虽然可以通过提取@字符、分别判断@前后的单词和域名来达到目的,但是这种做不仅繁琐,而且代码难以复用


正则表达式的设计思想是使用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,就会被认定为匹配,反之就是不匹配。而上述情况就可以使用正则表达式来进行匹配字符串,从而达到目的,并且可以进行复用。


使用正则表达式对上述需求进行操作的步骤是:


创建一个匹配Email的正则表达式

使用正则表达式匹配输入的字符串是否匹配


二、正则表达式描述符


  • 正则表达式同样也是使用字符串表示的,下面来了解如何使用正则表达式来描述字符:


==(1)==在正则表达式中,如果直接给出字符,就是精确匹配,使用\d可以匹配一个数字,使用\w可以匹配一个字母或者数字,例如:


00\d:可以匹配以00开头,以数字结尾,比如007、004等,但是无法匹配00A、00v这种的

\d\d\d:可以匹配三个任意数字,比如123、543等

\w\w\d:可以匹配前两位以字母或数字开头,以数字结尾,比如a33、cc3、4f1等

==(2)==使用.可以匹配任意字符,例如:


py.:可以匹配以py开头,以任意字符结尾,比如py4、pya、py-等

==(3)==想要匹配变长的字符,可以使用*表示匹配任意字符,包括0个字符,使用+表示至少1个字符,使用?表示0或1个字符,使用{n,m}表示n到m个字符,下面来看案例:


\d{3}\s+\d{3,8}:从左到右分析,\d{3}匹配3个数字,比如123这样,\s可以匹配一个空格,包括TAB等空白符,而\s+就表示匹配至少一个空格,例如' '、' '等,\d{3,8}表示匹配3到8个数字,表示数字的数量最少是3,最大是8,比如123456、123、12345678这样。通过这个正则表达式,可以匹配带区号的电话号码

==(4)==想要更加精确的匹配字符,可以使用[]表示范围:


[0-9a-zA-Z\_]:可以匹配一个数字、字母或者一个下划线


[0-9a-z-A-Z\_]+:可以匹配至少由1个数字、字母或下划线组成的字符串,匹配数量大于1


[a-zA-Z\_][0-9a-zA-Z\_]*:可以匹配由一个字母或下划线开头,然后接任意数量的由数字、字母、下划线组成的字符串


[a-zA-Z\_][0-9a-zA-Z\_]{0,19}:和上面的匹配规则相同,只是限制了字符的长度


==(5)==还有其他的特殊字符例如:


|:表示或的意思,比如A|B,可以匹配A或者B


^:表示开头,比如^A,就是匹配以A开头的


$:表示末尾,比如A$,就是匹配以A结尾的


注意:


如果不使用特殊字符,只是单纯的字符串的话,那么相当于是包含的意思,例如,正则表达式为py,而字符串第一行为python第二行为py,使用正则表达式会全部进行匹配,即两行字符串都会进行匹配,如果正则表达式为^py$,那么正则表达式就只会匹配第二行的py了


三、re模块


  • 通过上面的了解,我们就可以在Python中使用正则表达式了,Python提供了re模块,其中包含了所有正则表达式的功能
  • Python中有些字符串本身也是通过\转义的,而使用r前缀就无需考虑转义问题,例如:


- 通过 \ 进行转义
>>> s = 'ABC\\-001' 
>>> print(s) 
ABC\-001
- 使用 r 进行转义
>>> s = r'ABC\-001' 
>>> print(s)        
ABC\-001
  • 下面来看如何判断正则表达式是否匹配:


使用match()方法判断是否匹配,如果匹配成功会返回一个Match对象,反之返回None

match():第一个参数是正则表达式,第二个参数是要匹配的字符串

>>> import re
>>> re.match(r'^\d{3}\-\d{3,8}$','010-12345')   
<re.Match object; span=(0, 9), match='010-12345'>  #匹配成功返回match对象
>>> re.match(r'^\d{3}\-\d{3,8}$','010 12345') 
>>> a = re.match(r'^\d{3}\-\d{3,8}$','010 12345')
>>> print(a) 
None          #匹配不成功,返回None
  • 常见正则表达式判断方法:


test = '字符串'
if re.match(r'正则表达式',test):
    print('ok')
else:
    print('failed')


四、切分字符串


  • 使用正则表达式切分字符串比使用固定的字符更加灵活,下面是正常的切分代码:


>>> 'ab    c'.split(' ') 
['ab', '', '', '', 'c']    #可以看到无法识别连续的空格


使用正则表达式:

>>> re.split(r'\s+','ab   c')   
['ab', 'c']   #可以看到相同的字符串可以正常分割
>>> re.split(r'[\s\,]+','a,b, c  d')  #加入 , 进行分割
['a', 'b', 'c', 'd']
>>> re.split(r'[\s\,\:]+','a,b:::, c  d')  #加入 : 进行分割
['a', 'b', 'c', 'd']


五、分组


  • 除了简单的判断是否匹配之外,正则表达式还有提取子串的强大功能,使用()表示的就是要提取的分组Group,例如:


^(\d{3})-(\d{3,8})$:这个正则表达式定义了两个分组,可以直接从匹配的字符串中提取出区号和本地号码


>>> m = re.match(r'^(\d{3})-(\d{3,8})$','010-12345') 
>>> m
<re.Match object; span=(0, 9), match='010-12345'>
- 如果在正则表达式中定义了组,就可以在match对象上使用group()方法提取出子串来,例如:
>>> m.group(0)     #group(0)永远是整个匹配的字符串
'010-12345'
>>> m.group(1)     #后续的1、2、3...就代表着第1、2、3...个子串
'010'
>>> m.group(2) 

下面来看一个关于分组的案例

>>> t = '22:33:44' 
>>> m = re.match(r'^(0[0-9]|1[0-9]|2[0-3]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])\:(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])$', t)
>>> m.group(0) 
'22:33:44'
>>> m.group(1) 
'22'
>>> m.group(2) 
'33'
>>> m.group(3) 
'44'
  • 上述正则虽然可以匹配正常的日期格式,但是对2-304-31这样的非法日期还是无能为力,或者是写出来非常困难,这时就需要程序配合识别了


六、贪婪匹配


  • 正则表达式默认是贪婪匹配,也就是匹配尽可能多的字符串,例如:


- 匹配出数字后面的0
>>> re.match(r'^(\d+)(0*)$','102300').groups() 
('102300', '')


  • 由于\d+组采用贪婪匹配,直接把后面的0全部匹配了,结果0*组只能匹配空字符串了
  • 想让\d+采用非贪婪匹配,可以加个?即可:


>>> re.match(r'^(\d+?)(0*)$','102300').groups()
('1023', '00')
- 可以看到加了 ? 后,0* 组也匹配了字符串

七、编译


  • 在使用正则表达式时,Python的re模块内部会做两件事:


  1. 编译正则表达式,如果正则表达式的字符串本身语法不正确,那么就会报错
  2. 使用编译后的正则表达式去匹配字符串


可以看到每次使用正则表达式时都会经过编译的过程,如果一个正则表达式要使用上千次,每次都进行编译的效率显然是有点多余,所以处于效率的考虑,我们可以预编译使用的正则表达式,之后就无需编译这个步骤了,例如

>>> import re
>>> re_telephone = re.compile(r'^(\d{3})-(\d{3,8})$') 
>>> re_telephone.match('010-12345').groups()  
('010', '12345')
>>> re_telephone.match('010-80808').groups()  
('010', '80808')
  • 可以看到只需一次编译,后续直接就可以套用正则进行字符串匹配


八、案例


  • 匹配email:
# -*- coding: utf-8 -*-
from http.client import FAILED_DEPENDENCY
import re
def is_valid_email(addr):
    if re.match(r'^(\w+(\.)?\w+)@(\w+)(.com){1}$', addr):
        print("ok")
        return True
    else:
        print("faild")
        return False
# 测试:
assert is_valid_email('someone@gmail.com')
assert is_valid_email('bill.gates@microsoft.com')
assert not is_valid_email('bob#example.com')
assert not is_valid_email('mr-bob@example.com')
print('ok')
- 执行
ok
ok
faild
faild
ok


取出带名字的email地址

# -*- coding: utf-8 -*-
from http.client import FAILED_DEPENDENCY
import re
def name_of_email(addr):
    res = re.match(r'^<?(\w+\s?\w+)>?\s?(\w){0,}@(\w+\.\w+)', addr)
    if res:
        print(res.groups())  # 根据正则表达式括号部分分组                
        return res.group(1)
    else:
        return False
# 测试:
assert name_of_email('<Tom Paris> tom@voyager.org') == 'Tom Paris'
assert name_of_email('tom@voyager.org') == 'tom'
print('ok')
- 执行
('Tom Paris', 'm', 'voyager.org')
('tom', None, 'voyager.org')
ok


目录
相关文章
|
3月前
|
Python
"揭秘!Python如何运用神秘的正则表达式,轻松穿梭于网页迷宫,一键抓取隐藏链接?"
【8月更文挑战第21天】Python凭借其强大的编程能力,在数据抓取和网页解析领域表现出高效与灵活。通过结合requests库进行网页请求及正则表达式进行复杂文本模式匹配,可轻松提取网页信息。本示例展示如何使用Python和正则表达式解析网页链接。首先确保已安装requests库,可通过`pip install requests`安装。接着,利用requests获取网页内容,并使用正则表达式提取所有`&lt;a&gt;`标签的`href`属性。
44 0
|
5天前
|
Python
在Python中,可以使用内置的`re`模块来处理正则表达式
在Python中,可以使用内置的`re`模块来处理正则表达式
18 5
|
10天前
|
数据采集 Web App开发 iOS开发
如何使用 Python 语言的正则表达式进行网页数据的爬取?
使用 Python 进行网页数据爬取的步骤包括:1. 安装必要库(requests、re、bs4);2. 发送 HTTP 请求获取网页内容;3. 使用正则表达式提取数据;4. 数据清洗和处理;5. 循环遍历多个页面。通过这些步骤,可以高效地从网页中提取所需信息。
|
1月前
|
Python
【收藏备用】Python正则表达式的7个实用技巧
【收藏备用】Python正则表达式的7个实用技巧
21 1
|
1月前
|
数据安全/隐私保护 Python
Python实用正则表达式归纳
Python实用正则表达式归纳
|
1月前
|
Python
Python 正则表达式高级应用指南
正则表达式是文本模式匹配的强大工具,Python 的 `re` 模块支持其操作。本文介绍正则表达式的高级应用,包括复杂模式匹配(如邮箱、电话号码)、分组与提取、替换操作、多行匹配以及贪婪与非贪婪模式的区别。通过示例代码展示了如何灵活运用这些技巧解决实际问题。
27 7
|
1月前
|
JavaScript 前端开发 Scala
Python学习十:正则表达式
这篇文章是关于Python中正则表达式的使用,包括re模块的函数、特殊字符、匹配模式以及贪婪与非贪婪模式的详细介绍。
16 0
|
1月前
|
数据采集 开发者 Python
Python正则表达式之re.compile函数
`re.compile`是Python正则表达式处理中一个强大的工具,它通过预先编译正则表达式,不仅提升了执行效率,还增强了代码的组织性和可读性。掌握其使用,对于涉及文本分析、数据清洗、日志处理等领域的Python开发者来说,是非常必要的技能。正确并高效地应用这一功能,可以显著提升程序的性能和维护性。
65 0
|
2月前
|
索引 Python
30天拿下Python之正则表达式
30天拿下Python之正则表达式
17 0
|
2月前
|
数据采集 Python
Python正则表达式提取车牌号
Python正则表达式提取车牌号