前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python正则表达式

Python正则表达式

作者头像
用户2700375
发布2022-06-09 14:13:23
6020
发布2022-06-09 14:13:23
举报
文章被收录于专栏:很菜的web狗

如何把一个字符串的特征或规则告诉给计算机,让计算机知道你要描述的东西。被称为正则。

了解正则表达式

正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。在很多文本编辑器里,正则表达式通常被用来检索、替换那些匹配某个模式的文本。

如何把一个字符串的特征或规则告诉给计算机,让计算机知道你要描述的东西。被称为正则。

re模块操作

Python当中提供正则表达式的基本模块

模块当中提供了一些关于正则的方法

代码语言:javascript
复制
1、re.match(正则表达式,要匹配的字符串)

若字符串匹配正则表达式则match方法返回匹配对象,否则返回None

也可以在Match对象上用group()方法提取出子串来 如下

正则表达式的匹配规则

表示字符

字符

功能

.

匹配任意1个字符(除了\n)

[ ]

匹配[ ]中列举的字符

\d

匹配数字,即0-9

\D

匹配非数字,即不是数字

\s

匹配空白,即 空格,tab键

\S

匹配非空白

\w

匹配单词字符,即a-z、A-Z、0-9、_

\W

匹配非单词字符

表示数量

字符

功能

*

匹配前一个字符出现0次或者无限次,即可有可无

+

匹配前一个字符出现1次或者无限次,即至少有1次

?

匹配前一个字符出现1次或者0次,即要么有1次,要么没有

{m}

匹配前一个字符出现m次

{m,}

匹配前一个字符至少出现m次

{m,n}

匹配前一个字符出现从m到n次

表示边界

字符

功能

^

匹配字符串开头

$

匹配字符串结尾

\b

匹配一个单词的边界

\B

匹配非单词边界

匹配分组

字符

功能

\

\

匹配左右任意一个表达式

(ab)

将括号中字符作为一个分组

\num

引用分组num匹配到的字符串

(?P<name>)

分组起别名

(?P=name)

引用别名为name分组匹配到的字符串

更精准匹配

要做更精确地匹配,可以用[]表示范围

比如匹配手机号 在大陆手机号的第一位都是1

而第二位貌似只能是 3,4,5,7,8

那么要做到更精准我们可以这样写

上面有/d /D 大写表示取反的作用那[]也是可以取反的

前面加一个^就表示对括号里面的取反

小练习:匹配手机号的正则表达式

代码语言:javascript
复制
>>> import re
>>> re.match("^1[35678]\d{9}$","18711111111")
<re.Match object; span=(0, 11), match='18711111111'>

原始字符串

这块我最开始也是比较懵的 可能有点难理解

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

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

像用'\\\\'来匹配\的处理办法看上去太丑陋了。为了简化理解和操作,Python提供了原始字符串

'\\\\'在正则匹配函数中先被理解为'\\',而'\\'用来匹配待处理字符串,则再一次被理解为用\来匹配字符串。

实际案例

匹配出0-100之间的数字

代码语言:javascript
复制
>>> import re
>>> re.match(r"[1-9]?\d?$|100$","0")
<re.Match object; span=(0, 1), match='0'>
>>> re.match(r"[1-9]?\d?$|100$","100")
<re.Match object; span=(0, 3), match='100'>
>>> re.match(r"[1-9]?\d?$|100$","52")
<re.Match object; span=(0, 2), match='52'>

分组提取

代码语言:javascript
复制
>>> result = re.match(r"<h1>(.*)</h1>","<h1>匹配分组</h1>")
>>> result.group()
'<h1>匹配分组</h1>'
>>> result.group(1)
'匹配分组'

正则表达式中出现了一个括号 所以group(1)会提取出第一个括号里的内容

代码语言:javascript
复制
>>> result = re.match(r"(<h1>)(.*)(</h1>)","<h1>匹配分组</h1>")
>>> result.group(1)
'<h1>'
>>> result.group(3)
'</h1>'
>>> result.group(0)
'<h1>匹配分组</h1>'

group(0) 会提取出整个内容

分组进阶提取

我们都知道html标签都是会成对出现的

那么我们应该写一个可以成对匹配的正则表达式

代码语言:javascript
复制
>>> s = "<html><h1>itcast</h1></html>"
>>> re.match(r"<(.+)><(.+)>.+</\2></\1>",s)// \1表示第一个分组 \2表示第二个分组
<re.Match object; span=(0, 28), match='<html><h1>itcast</h1></html>'>
>>> s = "<html><h1>itcast</h2></script>"
>>> re.match(r"<(.+)><(.+)>.+</\2></\1>",s)

橙色框的案例 前后标签不同所以无法匹配

看起来这样做确实很不错 不过我如果有一万个分组那该怎么办

挨个数然后</\10000>么 显然不可能

还有一种方法 前面匹配的表里有些写过

给分组命名

代码语言:javascript
复制
import re

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

re模块高级用法

re.search

search方法与match方法极其类似,区别在于match()函数只检测re是不是在string的开始位置匹配,search()会扫描整个string查找匹配,match()只有在0位置匹配成功的话才有返回,如果不是开始位置匹配成功的话,match()就返回None。同样,search方法的返回对象同样match()返回对象的方法和属性

这种情况下match就无法匹配

re.findall

以列表形式返回全部能匹配的子串

符合匹配以后会继续往下寻找匹配的字符串

re.sub

将匹配到的数据进行替换

将标签替换为空 意思是只匹配文字

执行后效果为

re.split

根据匹配进行切割字符串,并返回一个列表

代码语言:javascript
复制
#split 匹配切割字符串
>>>c = "ctf:php,python,web-misc"
>>>d = re.split(r":|,|-",c)//用(: , -)为依据 分割字符串
>>>print(d)
['ctf', 'php', 'python', 'web', 'misc']

贪婪和非贪婪

Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;

非贪婪则相反,总是尝试匹配尽可能少的字符。

在”*”,”?”,”+”,”{m,n}”后面加上?,使贪婪变成非贪婪。

代码语言:javascript
复制
>>> s="This is a number 234-235-22-423"
>>> r=re.match(".+(\d+-\d+-\d+-\d+)",s)
>>> r.group(1)
'4-235-22-423'
>>> r=re.match(".+?(\d+-\d+-\d+-\d+)",s)
>>> r.group(1)
'234-235-22-423'

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

解决方式:非贪婪操作符“?”,这个操作符可以用在”*”,”+”,”?”的后面,要求正则匹配的越少越好。

小练习

1提取图片链接
代码语言:javascript
复制
e = 
"""

<img dataoriginal="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" src="https://rpic.ucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" style="display: inline;">

"""

f = re.search("http.+?\.jpg",e)

print(f.group())

结果为

代码语言:javascript
复制
https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg
2提取网址
代码语言:javascript
复制
http://www.interoem.com/messageinfo.asp?id=35

正则提取后为

代码语言:javascript
复制
http://www.interoem.com/

代码为

代码语言:javascript
复制
g = "http://www.interoem.com/messageinfo.asp?id=35"
h = re.sub("(http://.+?/).*",lambda x:x.group(1),g)
print(h)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-05-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 了解正则表达式
  • re模块操作
  • 正则表达式的匹配规则
    • 表示字符
      • 表示数量
        • 表示边界
          • 匹配分组
            • 更精准匹配
              • 小练习:匹配手机号的正则表达式
              • 原始字符串
              • 实际案例
                • 匹配出0-100之间的数字
                  • 分组提取
                    • 分组进阶提取
                    • re模块高级用法
                      • re.search
                        • re.findall
                          • re.sub
                            • re.split
                            • 贪婪和非贪婪
                              • 小练习
                                • 1提取图片链接
                                • 2提取网址
                            领券
                            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档