万能的正则表达式,有兴趣了解一下?

2024-04-17 08:18

本文主要是介绍万能的正则表达式,有兴趣了解一下?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

640?wx_fmt=gif

一、简介

现在我们在日常编程中好多地方都会用到正则表达式,例如做密码强度验证,手机号码格式验证,邮箱验证,就连现在的简单的爬虫,我们基本都是手写正则表达式做匹配的。那我们来看看正则表达式到底是什么?为什么会有这么神奇的力量?

正则表达式本身是一种小型的、高度专业化的编程语言,而在python中,通过内嵌集成re模块,我们可以直接调用来实现正则匹配。正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎执行。

二、正则表达式中常用的字符含义

1、普通字符和11个元字符:

普通字符匹配自身abcabc
.匹配任意除换行符"\n"外的字符(在DOTALL模式中也能匹配换行符a.cabc
\转义字符,使后一个字符改变原来的意思a\.c;a\\ca.c;a\c
*匹配前一个字符0或多次abc*ab;abccc
+匹配前一个字符1次或无限次abc+abc;abccc
?匹配一个字符0次或1次abc?ab;abc
^匹配字符串开头。在多行模式中匹配每一行的开头^abcabc
$匹配字符串末尾,在多行模式中匹配每一行的末尾abc$abc
|或。匹配|左右表达式任意一个,从左到右匹配,如果|没有包括在()中,则它的范围是整个正则表达式abc|def

abc

def

{}{m}匹配前一个字符m次,{m,n}匹配前一个字符m至n次,若省略n,则匹配m至无限次ab{1,2}c

abc

abbc

[]字符集。对应的位置可以是字符集中任意字符。字符集中的字符可以逐个列出,也可以给出范围,如[abc]或[a-c]。[^abc]表示取反,即非abc。
所有特殊字符在字符集中都失去其原有的特殊含义。用\反斜杠转义恢复特殊字符的特殊含义。
a[bcd]e

abe

ace

ade

 

()被括起来的表达式将作为分组,从表达式左边开始没遇到一个分组的左括号“(”,编号+1.
分组表达式作为一个整体,可以后接数量词。表达式中的|仅在该组中有效。
(abc){2}
a(123|456)c

abcabc

a456c

这里需要强调一下反斜杠\的作用:

  • 反斜杠后边跟元字符去除特殊功能;(即将特殊字符转义成普通字符)

  • 反斜杠后边跟普通字符实现特殊功能;(即预定义字符)

  • 引用序号对应的字组所匹配的字符串。

a=re.search(r'(tina)(fei)haha\2','tinafeihahafei tinafeihahatina').group()print(a)
结果:
tinafeihahafei

2、预定义字符集(可以写在字符集[...]中) 

\d数字:[0-9]a\bca1c
\D非数字:[^\d]a\Dcabc
\s匹配任何空白字符:[<空格>\t\r\n\f\v]a\sca c
\S非空白字符:[^\s]a\Scabc
\w匹配包括下划线在内的任何字字符:[A-Za-z0-9_]a\wcabc
\W匹配非字母字符,即匹配特殊字符a\Wca c
\A仅匹配字符串开头,同^\Aabcabc
\Z仅匹配字符串结尾,同$abc\Zabc
\b匹配\w和\W之间,即匹配单词边界匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。\babc\b
a\b!bc
空格abc空格
a!bc
\B[^\b]a\Bbcabc

这里需要强调一下\b的单词边界的理解:
w = re.findall('\btina','tian tinaaaa')print(w) s = re.findall(r'\btina','tian tinaaaa')print(s) v = re.findall(r'\btina','tian#tinaaaa')print(v) a = re.findall(r'\btina\b','tian#tina@aaa')print(a) 执行结果如下: [] ['tina'] ['tina'] ['tina']

3、特殊分组用法:

(?P<name>)分组,除了原有的编号外再指定一个额外的别名(?P<id>abc){2}abcabc
(?P=name)引用别名为<name>的分组匹配到字符串(?P<id>\d)abc(?P=id)

1abc1

5abc5

\<number>引用编号为<number>的分组匹配到字符串(\d)abc\1

1abc1

5abc5

三、re模块中常用功能函数

1、compile()

编译正则表达式模式,返回一个对象的模式。(可以把那些常用的正则表达式编译成正则表达式对象,这样可以提高一点效率。)

格式:

re.compile(pattern,flags=0)

pattern: 编译时用的表达式字符串。

flags 编译标志位,用于修改正则表达式的匹配方式,如:是否区分大小写,多行匹配等。常用的flags有:

标志含义
re.S(DOTALL)使.匹配包括换行在内的所有字符
re.I(IGNORECASE)使匹配对大小写不敏感
re.L(LOCALE)做本地化识别(locale-aware)匹配,法语等
re.M(MULTILINE)多行匹配,影响^和$
re.X(VERBOSE)该标志通过给予更灵活的格式以便将正则表达式写得更易于理解
re.U根据Unicode字符集解析字符,这个标志影响\w,\W,\b,\B

 

import re
tt = "Tina is a good girl, she is cool, clever, and so on..."

rr = re.compile(r'\w*oo\w*')print(rr.findall(tt)) #查找所有包含'oo'的单词


执行结果如下: ['good', 'cool']


2、match()

决定RE是否在字符串刚开始的位置匹配。//注:这个方法并不是完全匹配。当pattern结束时若string还有剩余字符,仍然视为成功。想要完全匹配,可以在表达式末尾加上边界匹配符'$'

格式:

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

print(re.match('com','comwww.runcomoob').group())

print(re.match('com','Comwww.runcomoob',re.I).group()) 执行结果如下: com com

3、search()

 格式:

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

re.search函数会在字符串内查找模式匹配,只要找到第一个匹配然后返回,如果字符串没有匹配,则返回None。

print(re.search('\dcom','www.4comrunoob.5com').group())
执行结果如下:
4com

*注:match和search一旦匹配成功,就是一个match object对象,而match object对象有以下方法:

  • group() 返回被 RE 匹配的字符串

  • start() 返回匹配开始的位置

  • end() 返回匹配结束的位置

  • span() 返回一个元组包含匹配 (开始,结束) 的位置

  • group() 返回re整体匹配的字符串,可以一次输入多个组号,对应组号匹配的字符串。

a. group()返回re整体匹配的字符串,
b. group (n,m) 返回组号为n,m所匹配的字符串,如果组号不存在,则返回indexError异常
c.groups()groups() 方法返回一个包含正则表达式中所有小组字符串的元组,从 1 到所含的小组号,通常groups()不需要参数,返回一个元组,元组中的元就是正则表达式中定义的组。 


 import rea = "123abc456"print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0))   #123abc456,返回整体print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1))   #123print(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2))   #abcprint(re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3))   #456
###group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分。###


4、findall()

re.findall遍历匹配,可以获取字符串中所有匹配的字符串,返回一个列表。

 格式:

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

p = re.compile(r'\d+')print(p.findall('o1n2m3k4'))
执行结果如下:
['1', '2', '3', '4']


import re
tt = "Tina is a good girl, she is cool, clever, and so on..."

rr = re.compile(r'\w*oo\w*')

print(rr.findall(tt))

print(re.findall(r'(\w)*oo(\w)',tt))#()表示子表达式

执行结果如下: ['good', 'cool'] [('g', 'd'), ('c', 'l')]


5、finditer()

 搜索string,返回一个顺序访问每一个匹配结果(Match对象)的迭代器。找到 RE 匹配的所有子串,并把它们作为一个迭代器返回。

格式:

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

iter = re.finditer(r'\d+','12 drumm44ers drumming, 11 ... 10 ...')

for i in iter:
    print(i)
    print(i.group())
    print(i.span())
执行结果如下:
<_sre.SRE_Match object; span=(0, 2), match='12'> 12
(0, 2)
<_sre.SRE_Match object; span=(8, 10), match='44'> 44
(8, 10)
<_sre.SRE_Match object; span=(24, 26), match='11'> 11
(24, 26)
<_sre.SRE_Match object; span=(31, 33), match='10'> 10
(31, 33)


6、split()

按照能够匹配的子串将string分割后返回列表。

可以使用re.split来分割字符串,如:re.split(r'\s+', text);将字符串按空格分割成一个单词列表。

格式:

re.split(pattern, string[, maxsplit])

maxsplit用于指定最大分割次数,不指定将全部分割。

print(re.split('\d+','one1two2three3four4five5'))
执行结果如下:
['one', 'two', 'three', 'four', 'five', '']

7、sub()

使用re替换string中每一个匹配的子串后返回替换后的字符串。

格式:

re.sub(pattern, repl, string, count)


import re
text = "JGood is a handsome boy, he is cool, clever, and so on..."
print(re.sub(r'\s+', '-', text))
执行结果如下: JGood-is-a-handsome-boy,-he-is-cool,-clever,-and-so-on...

其中第二个函数是替换后的字符串;本例中为'-'

第四个参数指替换个数。默认为0,表示每个匹配项都替换。


re.sub还允许使用函数对匹配项的替换进行复杂的处理。

如:re.sub(r'\s', lambda m: '[' + m.group(0) + ']', text, 0);将字符串中的空格' '替换为'[ ]'。

import re
text = "JGood is a handsome boy, he is cool, clever, and so on..."print(re.sub(r'\s+', lambda m:'['+m.group(0)+']', text,0))
执行结果如下:
JGood[ ]is[ ]a[ ]handsome[ ]boy,[ ]he[ ]is[ ]cool,[ ]clever,[ ]and[ ]so[ ]on...

8、subn()

 返回替换次数

格式:

subn(pattern, repl, string, count=0, flags=0)


print(re.subn('[1-2]','A','123456abcdef'))
print(re.sub("g.t","have",'I get A,  I got B ,I gut C'))
print(re.subn("g.t","have",'I get A,  I got B ,I gut C'))
执行结果如下: ('AA3456abcdef', 2) I have A,  I have B ,I have C ('I have A,  I have B ,I have C', 3)


四、一些注意点

1、re.match与re.search与re.findall的区别:

re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。


a=re.search('[\d]',"abc33").group()
print(a) p=re.match('[\d]',"abc33")
print(p) b=re.findall('[\d]',"abc33")
print(b)
执行结果:
3
None ['3', '3']


2、贪婪匹配与非贪婪匹配

*?,+?,??,{m,n}?    前面的*,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配


a = re.findall(r"a(\d+?)",'a23b')print(a)
b = re.findall(r"a(\d+)",'a23b')print(b)
执行结果:
['2']
['23']


a = re.match('<(.*)>','<H1>title<H1>').group()print(a)
b = re.match('<(.*?)>','<H1>title<H1>').group()print(b)
执行结果:<H1>title<H1>
<H1>


a = re.findall(r"a(\d+)b",'a3333b')print(a)
b = re.findall(r"a(\d+?)b",'a3333b')print(b)
执行结果如下:
['3333']
['3333']#######################这里需要注意的是如果前后均有限定条件的时候,就不存在什么贪婪模式了,非匹配模式失效。


 3、用flags时遇到的小坑

print(re.split('a','1A1a2A3',re.I))#输出结果并未能区分大小写

这是因为re.split(pattern,string,maxsplit,flags)默认是四个参数,当我们传入的三个参数的时候,系统会默认re.I是第三个参数,所以就没起作用。如果想让这里的re.I起作用,写成flags=re.I即可。 

五、正则的小实践

1、匹配电话号码

p = re.compile(r'\d{3}-\d{6}')print(p.findall('010-628888'))

2、匹配IP

re.search(r"(([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5]\.)","192.168.1.1")



正则表达式差不多就到这里啦!

640?wx_fmt=jpeg


听说有气质的人都会关注这个公众号!

640?wx_fmt=jpeg


这篇关于万能的正则表达式,有兴趣了解一下?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/911262

相关文章

正则表达式高级应用与性能优化记录

《正则表达式高级应用与性能优化记录》本文介绍了正则表达式的高级应用和性能优化技巧,包括文本拆分、合并、XML/HTML解析、数据分析、以及性能优化方法,通过这些技巧,可以更高效地利用正则表达式进行复杂... 目录第6章:正则表达式的高级应用6.1 模式匹配与文本处理6.1.1 文本拆分6.1.2 文本合并6

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

速了解MySQL 数据库不同存储引擎

快速了解MySQL 数据库不同存储引擎 MySQL 提供了多种存储引擎,每种存储引擎都有其特定的特性和适用场景。了解这些存储引擎的特性,有助于在设计数据库时做出合理的选择。以下是 MySQL 中几种常用存储引擎的详细介绍。 1. InnoDB 特点: 事务支持:InnoDB 是一个支持 ACID(原子性、一致性、隔离性、持久性)事务的存储引擎。行级锁:使用行级锁来提高并发性,减少锁竞争

【详细介绍一下GEE】

GEE(Google Earth Engine)是一个强大的云计算平台,它允许用户处理和分析大规模的地球科学数据集,如卫星图像、气候模型输出等。以下是对GEE用法的详细介绍: 一、平台访问与账户设置 访问GEE平台: 用户可以通过访问Google Earth Engine的官方网站来开始使用GEE。 创建账户: 用户需要注册并登录Google账户,然后申请访问GEE平台。申请过程可能需要提

PHP: 深入了解一致性哈希

前言 随着memcache、redis以及其它一些内存K/V数据库的流行,一致性哈希也越来越被开发者所了解。因为这些内存K/V数据库大多不提供分布式支持(本文以redis为例),所以如果要提供多台redis server来提供服务的话,就需要解决如何将数据分散到redis server,并且在增减redis server时如何最大化的不令数据重新分布,这将是本文讨论的范畴。 取模算法 取模运

Weex入门教程之1,了解Weex

【资料合集】Weex Conf回顾集锦:讲义PDF+活动视频! PDF分享:链接:http://pan.baidu.com/s/1hr8RniG 密码:fa3j 官方教程:https://weex-project.io/cn/v-0.10/guide/index.html 用意 主要是介绍Weex,并未涉及开发方面,好让我们开始开发之前充分地了解Weex到底是个什么。 以下描述主要摘取于

JavaScript正则表达式六大利器:`test`、`exec`、`match`、`matchAll`、`search`与`replace`详解及对比

在JavaScript中,正则表达式(Regular Expression)是一种用于文本搜索、替换、匹配和验证的强大工具。本文将深入解析与正则表达式相关的几个主要执行方法:test、exec、match、matchAll、search和replace,并对它们进行对比,帮助开发者更好地理解这些方法的使用场景和差异。 正则表达式基础 在深入解析方法之前,先简要回顾一下正则表达式的基础知识。正则

Java了解相对较多!

我是对Java了解相对较多,而对C#则是因工作需要才去看了一下,C#跟Java在语法上非常相似,而最初让我比较困惑的就是委托、事件部分,相信大多数初学者也有类似的困惑。经过跟Java的对比学习,发现这其实跟Java的监听、事件是等同的,只是表述上不同罢了。   委托+事件是观察者模式的一个典型例子,所谓的委托其实就是观察者,它会关心某种事件,一旦这种事件被触发,这个观察者就会行动。   下

使用WebP解决网站加载速度问题,这些细节你需要了解

说到网页的图片格式,大家最常想到的可能是JPEG、PNG,毕竟这些老牌格式陪伴我们这么多年。然而,近几年,有一个格式悄悄崭露头角,那就是WebP。很多人可能听说过,但到底它好在哪?你的网站或者项目是不是也应该用WebP呢?别着急,今天咱们就来好好聊聊WebP这个图片格式的前世今生,以及它值不值得你花时间去用。 为什么会有WebP? 你有没有遇到过这样的情况?网页加载特别慢,尤其是那

匹配电子邮件地址的正则表达式

这个正则表达式 QRegularExpression regex(R"((\w+)(\.|_)?(\w+)@(\w+)(\.(\w+))+))"); 用于匹配电子邮件地址的格式。下面是对这个正则表达式的逐步解析和解释: 1. QRegularExpression 构造函数 QRegularExpression regex(R"((\w+)(\.|_)?(\w*)@(\w+)(\.(\w+))+