加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

09.正则表达式re-1.正则表达式

发布时间:2020-12-14 06:15:11 所属栏目:百科 来源:网络整理
导读:1、正则表达式概述 正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE),是计算机科学的一个概念。 正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。 在很多文本编辑器里,正则表达式通常被用来检索、替换那

1、正则表达式概述

正则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE),是计算机科学的一个概念。
正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。

2、re模块

2.1re 模块

使 Python语言拥有全部的正则表达式功能。
re 模块提供了一些函数,这些函数使用一个模式字符串做为它们的第一个参数,用于正则表达式匹配和替换。

2.2re模块的使用

  • re.match 函数

re.match 尝试从字符串的起始位置匹配一个模式,若字符串起始位置匹配正则表达式,则match方法返回匹配对象(Match Object),如果不是起始位置匹配成功的话,match()就返回none(注意不是“空字符串”)。

  • 语法:

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

  • 参数:
pattern – 匹配的正则表达式 

string – 要匹配的字符串。 

flags – 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

匹配对象Macth Object具有group方法,我们可以使用group(num) 或 groups() 匹配对象函数来获取匹配表达式。

group(num=0) 
匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。 

groups() 
返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
示例1:

# 导入re模块
import re

# 使用match方法进行匹配操作
result = re.match(正则表达式,要匹配的字符串)

# 如果上一步匹配到数据的话,可以使用group方法来提取数据
result.group()
示例2:

import re

ret = re.match("taobao","taobao.com")
print(ret)
print(ret.group())

运行结果:

<_sre.SRE_Match object; span=(0,6),match=‘taobao‘>
taobao

3、表示字符

正则表达式的单字符匹配:

字体 功能
. 匹配任意一个字符(除了n)
[] 匹配[]中列举的字符
d 匹配数字,即0-9
D 匹配非数字,即不是数字
s 匹配空白,即 空格,tab键
S 匹配非空白
w ==匹配包括下划线的任何单词字符。类似但不等价于“[A-Za-z0-9_]”,这里的"单词"字符使用Unicode字符集。==
W 匹配非单词字符

匹配中文字符的正则表达式: [u4e00-u9fa5]

  • 示例1:‘.’

匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符。

ret = re.match(‘.‘,‘a‘)
print(ret.group())

ret = re.match(‘.‘,‘A‘)
print(ret.group())

ret = re.match(‘.‘,‘ ‘)
print(ret.group())

ret = re.match(‘.‘,‘nab‘)
print(ret.group())     错误

ret = re.match(‘..‘,‘rab‘)
print(ret.group())

ret = re.match(‘..‘,‘tab‘)
print(ret.group())

ret = re.match(‘.‘,‘好好学习‘)
print(ret.group())

ret = re.match(‘....‘,‘好好学习‘)
print(ret.group())
  • 示例2:’[ ]‘

用来表示一组字符,单独列出:[amk] 匹配 ‘a’,’m’或’k’

ret = re.match(‘[Hh]‘,‘hello‘)
print(ret.group())

ret = re.match(‘[Hh]‘,‘Hello‘)
print(ret.group())

ret = re.match(‘[A-Z]‘,‘Hello‘)
print(ret.group())

ret = re.match(‘[0-9a-z]‘,‘00‘)
print(ret.group())

ret = re.match(‘[0-9a-z]‘,‘aa‘)
print(ret.group())

ret = re.match(‘[u4e00-u9fa5]*‘,‘陈佳睿‘)
print(ret)
print(ret.group())
  • 示例3:’d,D,s,S‘

d – 匹配一个数字字符。等价于 [0-9]。

D –匹配一个非数字字符。等价于 [^0-9]。

s –匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ fnrtv]。

S –匹配任何非空白字符。等价于 [^ fnrtv]。

ret = re.match(‘小米d‘,‘小米6‘)
print(ret.group())

ret = re.match(‘小Dd‘,‘小米6‘)
print(ret.group())

ret = re.match(‘s‘,‘ 小米‘)
print(ret)

ret = re.match(‘s‘,‘nab‘)
print(ret)

ret = re.match(‘S‘,‘小米‘)
print(ret)

ret = re.match(‘S‘,‘0123‘)
print(ret)

ret = re.match(‘SSS‘,‘x米6‘)
print(ret)


运行结果:
小米6
小米6
<_sre.SRE_Match object; span=(0,1),match=‘ ‘>
<_sre.SRE_Match object; span=(0,match=‘n‘>
<_sre.SRE_Match object; span=(0,match=‘小‘>
<_sre.SRE_Match object; span=(0,match=‘0‘>
<_sre.SRE_Match object; span=(0,3),match=‘x米6‘>
  • 示例4:’w,W‘

w ==匹配包括下划线的任何单词字符。类似但不等价于“[A-Za-z0-9_]”,这里的"单词"字符使用Unicode字符集。==。

W 匹配任何非单词字符。等价于 ‘[^A-Za-z0-9_]’。

ret = re.match(‘w‘,‘hello‘)
print(ret)

ret = re.match(‘ww‘,‘_hello‘)
print(ret)

ret = re.match(‘w‘,‘陈‘)
print(ret)

ret = re.match(‘WWw‘,‘。.Hello‘)
print(ret)

ret = re.match(‘W‘,‘陈hello‘)
print(ret)  #None

ret = re.match(‘W‘,‘陈hello‘,re.ASCII) #匹配各个国家文字
print(ret)  #<_sre.SRE_Match object; span=(0,match=‘陈‘>
ret = re.match(‘[u4e00-u9fa5]‘,‘哈hello‘)
print(ret)

运行结果:
<_sre.SRE_Match object; span=(0,match=‘h‘>
<_sre.SRE_Match object; span=(0,2),match=‘_h‘>
<_sre.SRE_Match object; span=(0,match=‘陈‘>
<_sre.SRE_Match object; span=(0,match=‘。.H‘>
None
<_sre.SRE_Match object; span=(0,match=‘哈‘>

4、原始字符串

>>> mm = "c:abc"
>>> mm
‘c:abc‘
>>> print(mm)
c:abc
>>> print(mm)
c:abc
>>> re.match("c:\",mm).group()
‘c:‘
>>> ret = re.match("c:\",mm).group()
>>> print(ret)
c:>>> ret = re.match("c:\a",mm).group()
>>> print(ret)
c:a
>>> ret = re.match(r"c:a",mm).group()
>>> print(ret)
c:a
>>> ret = re.match(r"c:a",mm).group()
Traceback (most recent call last):
  File "<stdin>",line 1,in <module>
AttributeError: ‘NoneType‘ object has no attribute ‘group‘

python中字符串前面加上 r 表示原生字符串

与大多数编程语言相同,正则表达式里使用””作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符””,那么使用编程语言表示的正则表达式里将需要4个反斜杠””:前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。

Python里的原生字符串很好地解决了这个问题,有了原始字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。

>>> ret = re.match(r"c:a",mm).group()
>>> print(ret)
c:a

5、表示数量

匹配多个字符的相关格式

字符 功能
* 匹配前一个字符出现0次或者无限次,即可有可无
+ 匹配前一个字符出现1次或者无限次,即至少有1次
? 匹配前一个字符出现1次或者0次,即要么有1次,要么没有
{m} 匹配前一个字符出现m次
{m,} 匹配前一个字符至少出现m次
{m,n} 匹配前一个字符出现从m到n次

6、表示边界

字符 功能
^ 匹配字符串开头
$ 匹配字符串结尾
b 匹配一个单词的边界
B 匹配非单词边界
  • 示例1:$

需求:匹配163.com的邮箱地址

import re

# 正确的地址
ret = re.match("[w]{4,20}@163.com","[email?protected]")
ret.group()

# 不正确的地址
ret = re.match("[w]{4,"[email?protected]")
ret.group()

# 通过$来确定末尾
ret = re.match("[w]{4,20}@163.com$","[email?protected]")
ret.group()
  • 示例2: b
>>> re.match(r".*bverb","ho ver abc").group()
‘ho ver‘

>>> re.match(r".*bverb","ho verabc").group()
Traceback (most recent call last):
  File "<stdin>",in <module>
AttributeError: ‘NoneType‘ object has no attribute ‘group‘

>>> re.match(r".*bverb","hover abc").group()
Traceback (most recent call last):
  File "<stdin>",in <module>
AttributeError: ‘NoneType‘ object has no attribute ‘group‘
  • 示例3:B
>>> re.match(r".*BverB","hoverabc").group()
‘hover‘

>>> re.match(r".*BverB",in <module>
AttributeError: ‘NoneType‘ object has no attribute ‘group‘

>>> re.match(r".*BverB","ho ver abc").group()
Traceback (most recent call last):
  File "<stdin>",in <module>
AttributeError: ‘NoneType‘ object has no attribute ‘group‘

7、匹配分组

字符 功能
| 匹配左右任意一个表达式
(ab) 将括号中字符作为一个分组
num 引用分组num匹配到的字符串
(?P 分别起组名
(?P=name) 引用别名为name分组匹配到字符串
  • 示例1:|

需求:匹配出0-100之间的数字

import re

ret = re.match("[1-9]?d","8")
print(ret)

ret = re.match("[1-9]?d","78")
print(ret)

# 不能正常匹配到的情况
ret = re.match("[1-9]?d","08")
print(ret)

# 修正之后的
ret = re.match("[1-9]?d$","8")
print(ret)

# 添加|
ret = re.match("[1-9]?d$|100","8")
print(ret)

ret = re.match("[1-9]?d$|100","78")
print(ret)

ret = re.match("[1-9]?d$|100","100")
print(ret)

运行结果:
<_sre.SRE_Match object; span=(0,match=‘8‘>
<_sre.SRE_Match object; span=(0,match=‘78‘>
<_sre.SRE_Match object; span=(0,match=‘100‘>
  • 示例2:( )

需求:匹配出163、126、qq邮箱之间的数字

import re

ret = re.match("w{4,"[email?protected]")
ret.group()

ret = re.match("w{4,20}@(163|126|qq).com","[email?protected]")
ret.group()

ret = re.match("w{4,"[email?protected]")
ret.group()

ret = re.match("w{4,"[email?protected]")
ret.group()
>>> ret = re.match("([^-]*)-(d+)","010-12345678")
>>> ret.group()
‘010-12345678‘
>>> ret.group(1)
‘010‘
>>> ret.group(2)
‘12345678‘
  • 示例3:

需求:匹配出hh

import re

# 能够完成对正确的字符串的匹配
ret = re.match("<[a-zA-Z]*>w*</[a-zA-Z]*>","<html>hh</html>")
ret.group()

# 如果遇到非正常的html格式字符串,匹配出错
ret = re.match("<[a-zA-Z]*>w*</[a-zA-Z]*>","<html>hh</htmlbalabala>")
ret.group()

# 正确的理解思路:如果在第一对<>中是什么,按理说在后面的那对<>中就应该是什么

# 通过引用分组中匹配到的数据即可,但是要注意是元字符串,即类似 r""这种格式
ret = re.match(r"<([a-zA-Z]*)>w*</1>","<html>hh</html>")
ret.group()

# 因为2对<>中的数据不一致,所以没有匹配出来
ret = re.match(r"<([a-zA-Z]*)>w*</1>","<html>hh</htmlbalabala>")
ret.group()
  • 示例4:number

需求:匹配出

www.taobao.com

import re

ret = re.match(r"<(w*)><(w*)>.*</2></1>","<html><h1>www.taobao.com</h1></html>")
ret.group()

ret = re.match(r"<(w*)><(w*)>.*</2></1>","<html><h1>www.taobao.com</h2></html>")
ret.group()
  • 示例5:(?P

需求:匹配出

www.taobao.com

import re

ret = re.match(r"<(?P<name1>w*)><(?P<name2>w*)>.*</(?P=name2)></(?P=name1)>","<html><h1>www.taobao.com</h1></html>")
ret.group()

ret = re.match(r"<(?P<name1>w*)><(?P<name2>w*)>.*</(?P=name2)></(?P=name1)>","<html><h1>www.taobao.com</h2></html>")
ret.group()

(?P

8、re模块的高级用法

需求:匹配出文章阅读的次数
import re

ret = re.search(r"d+","阅读次数为 9999")
print(ret.group())

9999

8.2findall

需求:统计出python、c、c++相应文章阅读的次数
import re

ret = re.findall(r"d+","python = 9999,c = 7890,c++ = 12345")
print(ret)

[‘9999‘,‘7890‘,‘12345‘]

8.3sub 将匹配到的数据进行替换

需求:将匹配到的阅读次数加1
方法1:
import re

ret = re.sub(r"d+",‘998‘,"python = 997")
print(ret)

python = 998





方法2:
import re

def add(temp):
    strNum = temp.group()
    num = int(strNum) + 1
    return str(num)

ret = re.sub(r"d+",add,"python = 997 java=100")
print(ret)

ret = re.sub(r"d+","python = 99")
print(ret)


python = 998 java=101
python = 100
从下面的字符串中取出文本
<div>
        <p>岗位职责:</p>
<p>完成推荐算法、数据统计、接口、后台等服务器端相关工作</p>
<p><br></p>
<p>必备要求:</p>


re.sub(r‘</?w*>|n|s‘,‘‘,s)

8.4split

  • 根据匹配进行切割字符串,并返回一个列表
需求:切割字符串“info:xiaoZhang 33 shandong”


import re

ret = re.split(r‘:| ‘,‘info:xiaoZhang 33 shandong‘)
print(ret)


[‘info‘,‘xiaoZhang‘,‘33‘,‘shandong‘]

9、贪婪和非贪婪

Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;
非贪婪则相反,总是尝试匹配尽可能少的字符。
在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪。

s="This is a number 234-235-22-423"

ret = re.match(".+(d+-d+-d+-d+)",s)
print(ret.group())

This is a number 234-235-22-423

ret = re.match(".+?(d+-d+-d+-d+?)",s)
print(ret.group())

This is a number 234-235-22-4

正则表达式模式中使用到通配字,那它在从左到右的顺序求值时,会尽量“抓取”满足匹配最长字符串,在我们上面的例子里面,“.+”会从字符串的启始处抓取满足模式的最长字符,其中包括我们想得到的第一个整型字段的中的大部分,“d+”只需一位字符就可以匹配,所以它匹配了数字“4”,而“.+”则匹配了从字符串起始到这个第一位数字4之前的所有字符。 解决方式:非贪婪操作符“?”,这个操作符可以用在"*","?"的后面,要求正则匹配的越少越好。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读