【Python入门】23.正则表达式

摘要:正则表达式的基本介绍;常用字符和语法介绍;re模块;贪婪匹配


*写在前面:为了更好的学习python,博主记录下自己的学习路程。本学习笔记基于廖雪峰的Python教程,如有侵权,请告知删除。欢迎与博主一起学习Pythonヽ( ̄▽ ̄)ノ *


目录

正则表达式
基本字符和语法
• 元字符
• 限定符
• 常用语法
re模块
• re.match( )
• re.split( )
• group( )
贪婪匹配
编译
小结
正则表达式

正则表达式

正则表达式是一种对字符串操作的逻辑公式,也就是记录文本规则的代码。它用一种描述性的语言来给字符串定义一个规则如果字符串符合这个规则,则说明这个字符串时匹配的。

举个例子,我们要判断一个字符串是否为邮箱,那么我们先创建一个匹配邮箱的正则表达式。将这个正则表达式与输入的字符串匹配,如果匹配成功,那么这个字符串就是一个邮箱。

基本字符和语法

首先了解一下正则表达式里面基本的字符描述:

• 元字符
代码 说明 例子
. 匹配换行符以外的所有字符 py. 匹配py3或pya或py!或py1234567
\w 匹配字母或数字或下划线或汉字 py\w 匹配py3或py_或pya或py1234567或pyasd,456
\s 匹配任意空白符,包括空格,制表符(Tab),换行符,中文全角空格等 p\sy 匹配p y或p\ny
\d 匹配数字 \w\w\d 匹配123或a12或ab2
\b 匹配单词的开始或结束 \b\w\d\b 匹配12或a1
^ 匹配字符串的开始 ^\w\w\w\w 匹配abc123
$ 匹配字符串的结束 ^\w\w\w\w$ 匹配abc1

其中\b^$都是用来匹配位置的,如果只有\w,那么只要有字母或数字或下划线或汉字就能匹配,而没有限制多少个。加上\b^$这些匹配位置的字符就能限制匹配对象为一个单词或是一个字符串。

• 限定符

|代码/语法|说明|例子
|--|--|
|*|重复零次或更多次|\b\d\w*\b 匹配1或1abc|
|+|重复一次或更多次|\b\d\w+\b 匹配1a或1abc|
|?|重复零次或一次|\b\d\w+\b 匹配1或1a|
|{n}|重复n次|\b\dx{3}\b 匹配1xxx|
|{n,}|重复n次或更多次|\b\dx{3,}\b 匹配1xxx或1xxxxx|
|{n,m}|重复n到m次|\b\dx{2,5}\b 匹配1xx或1xxx或1xxxxx|

• 常用语法

在介绍了一些基本的字符之后,我们再来看看常用的语法:

  • [ ]可以表示范围,像这样:

[abcde]可以匹配字符abcde里面的其中一个;
[a-z]可以匹配所有的小写字母
[[0-9a-zA-Z\_]]可以匹配一个数字或字母或下划线,相当于\w
[a-zA-Z\\_][0-9a-zA-Z\\_]*可以匹配以字母或下划线开头,后续接任意数字或字母或下划线组成的字符串,也就是Python的合法变量。

  • |可以表示分枝条件,相当于或,像这样:

A|B可以匹配A或B
[a-z]|A可以匹配所有的小写字母或者A

  • 如果我们要匹配一些特殊字符如-,就要用到转义字符\

比如我们要匹配010-12345这样的号码,就要这样写正则表达式:\d{3}\-\d{3,8}

当然在python有强大的r前缀,这样就不用考虑转义的问题了。

re模块

Python提供的re模块,包含了正则表达式的全部功能。

• re.match( )

我们可以通过re.match( )函数来判断一个字符串与正则表达式是否匹配。

函数语法:

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

参数说明:

pattern表示匹配的正则表达式
string表示需要匹配的字符串
flags表示标志位,用于控制正则表达式的匹配方式,如是否多行匹配,是否区分大小写等

配合if语句就可以轻松判断,输入的字符串是否与正则表达式相匹配:

import re
if re.match(r'\d{3}-\d{3,8}','010-1234567'):
    print('OK!')
else:
    print('Failed.')

执行结果:

OK!
• re.split( )

re.split( )可以按照能够匹配的子串来切割字符串,相比用固定的字符来切割更灵活。
固定字符切割:

>>> 'a b   c'.split(' ')
['a', 'b', '', '', 'c']

可见按照固定字符空格切割,并不能识别连续的空格。

正则表达式re.split( )切割:

>>> re.split(r'\s+', 'a b   c')
['a', 'b', 'c']

\s+表示匹配子串为一个或任意个空格。这样就可以识别连续的空格了。

还能加上其他字符,进行识别切割:

>>> re.split(r'[\s\,\;]+', 'a,b, c ; d')
['a', 'b', 'c', 'd']
• group( )

通过group( )我们能提取匹配字符串的子串,比如这个正则表达式:^(\d{3})-(\d{3,8})$,分别用()定义了两个组,然后我们即可以通过group( )来提取这两个组的内容,即提取出区号和本地号码:

>>> m = re.match(r'^(\d{3})-(\d{3,8})$', '010-1234567')
>>> m
<_sre.SRE_Match object; span=(0, 11), match='010-1234567'>
>>> m.group(0)
'010-1234567'
>>> m.group(1)
'010'
>>> m.group(2)
'1234567'

其中group(0)表示原始字符串,group(1)表示第一个子串,group(2)表示第二个子串,以此类推。
也可以用groups( )来返回所有子串:

>>>m.groups()
('010', '1234567') 

贪婪匹配

正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符,如:

>>> re.match(r'^(\d+)(0*)$', '102300').groups()
('102300', '')

正则表达式^(\d+)(0*)$表示匹配以一个或任意多个数字开头,后续接以零个或无数个0组成的字符串,并把前面的数字与后面0分组。

正则匹配默认贪婪匹配,所以第一个分组就把符合规则的所有数字102300匹配进去了,而第二个分组则没有匹配到0。

我们可以手动设置为非贪婪匹配,即匹配尽可能少的字符。把+改成+?+?表示重复一次或多次但尽可能少重复。

>>> 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-1234567').groups()
('010', '1234567')
>>> re_telephone.match('010-8086').groups()
('010', '8086')

其中re.compile( )函数用于编译正则表达式,生成Regular Expression对象,然后调用对应的方法时不用再给出正则表达式。

小结

正则表达式的内容十分多,本节内容仅供初步了解。如果常用到正则表达式,那么需要有一份正则表达式语法参考手册来参考使用。

想要了解更多的正则表达式内容,推荐学习:正则表达式30分钟入门教程


以上就是本节的全部内容,感谢你的阅读。

下一节内容:常用内建模块介绍

有任何问题与想法,欢迎评论与吐槽。

和博主一起学习Python吧( ̄▽ ̄)~*

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容

  • python的re模块--细说正则表达式 可能是东半球最详细最全面的re教程,翻译自官方文档,因为官方文档写的是真...
    立而人阅读 22,824评论 4 46
  • Python中的正则表达式(re) import rere.match #从开始位置开始匹配,如果开头没有则无re...
    BigJeffWang阅读 7,043评论 0 99
  • 搞懂Python 正则表达式用法 Python 正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一...
    厦热阅读 1,562评论 0 2
  • re模块手册 本模块提供了和Perl里的正则表达式类似的功能,不关是正则表达式本身还是被搜索的字符串,都可以...
    喜欢吃栗子阅读 3,974评论 0 13
  • Swift不允许整型变量或者常量被赋值一个超出其表数范围的数值,如果试图这么干,则会出现运行时错误: 如果希望数据...
    anyurchao阅读 2,765评论 0 1