Python进阶1 - 正则表达式: 一文掌握正则表达式编程

小马哥正在为Python的所有常见知识进行汇总,更会有大量实战项目
点击--> 全栈工程师养成---Python内容导航页 <--查看所有Python内容

导语

正则表达式本质是一种字符串模式或者叫字符串模板,用来匹配一些列的字符串,找到目标字符串的过程就是匹配或者搜索,找到这些目标字符串之后,就可以对其进行提取,进行拆分,进行替换等等. 这也就是正则表达式和编程语言的逻辑关系,正则表达式规定了如何定义模式,编程语言使用正则表达式确定的逻辑模式,进行功能实现(匹配,搜索,提取,查分,替换等功能).

主要内容:

  • (2)先使用Python的re模块,实现正则表达式编程
  • (1)正则表达式基本知识点

我故意把顺序倒过来,虽然先有正则再有Python对正则表达式的支持, 我们先把知识用起来,然后不用太多解释,你已经清楚正则是用来干什么了.目的还是保证: 一篇文章精通正则表达式,以及Python使用正则表达式熟练编程.

(一)用Python针对正则表达式编程

先把"见猪跑",直观认识正则表达式与Python利用正则表达式实现一定功能,介绍常用的函数或者方法

1.1 match()函数

作用: 匹配正则表达式,如果匹配成功就返回一个匹配对象;如果匹配失败,就返回None. 匹配对象的group()方法用于显示成功的匹配.

例1,实现最简单的正则表达式,

import re
# 正则表达式模式
pattern = 'China'
# 字符串文本
data = 'China'
# 通过re模块的的match方法,从data的起始部分开始,对正则表达式模式进行比对,如果匹配,返回一个匹配对象;否则返回None
result = re.match(pattern,data)
print(type(result))  # 返回 <class 're.Match'>
print(result.group()) # Match对象的group()会返回成功的匹配.

例2,最简单的正则表达式模式,之如果匹配失败是什么样子的

import re

pattern = 'China'
datas= 'Chinese','Python','China is a great country'

for data in datas:
    result = re.match(pattern,data)
    if result is not None:
        print("匹配成功: ",result)
    else:
        print('匹配失败: ',data)
匹配失败:  Chinese
匹配失败:  Python
匹配成功:  <re.Match object; span=(0, 5), match='China'>

上面的模式(或者认为是模板)中,pattern就是一个简单的字符串,但是这样的模式只能匹配一个单词,如果想匹配更多的情况,模式应该怎么写?

例3,能够匹配一个范围的字符

import re
pattern = '[abc]'   #使用[]括起来的内容,代表一个集合,代表匹配集合内的任意一个字符,[abc]代表可以匹配a或者b或者c
datas = 'a','b','c','e','xay'

for data in datas:
    result = re.match(pattern,data)
    if result is not None:
        print('Match Successfully: ',result.group())  # group()函数的作用: 返回Match对象匹配到的字符内容
    else:
        print('Match Failed: ',data)

例4,上面的例子中[abc]指代了一个集合,元素之间是或的关系,也可以把这个集合看做一个范围,

还有一种表示方法[a-z][A-Z][0-9],也是指代范围,[a-c]也是同样的意思

import re
pattern = '[a-e]'   #[a-e]代表了a到e这个字符范围内的任何一个字符
datas = 'a','b','c','e','xay'

for data in datas:
    result = re.match(pattern,data)
    if result is not None:
        print('Match Successfully: ',result.group())  # group()函数的作用: 返回Match对象匹配到的字符内容
    else:
        print('Match Failed: ',data)

例5,点号'.' 匹配任意的单个字符(换行符和非字符除外)

import re
pattern = '李.'
names='李逵','李鬼','小李'
for name in names:
    isMatched = re.match(pattern,name)
    if isMatched:
        print('Match Successfully: ',isMatched)
    else:
        print('Match Faied: ',name)
Match Successfully:  <re.Match object; span=(0, 2), match='李逵'>
Match Successfully:  <re.Match object; span=(0, 2), match='李鬼'>
Match Faied:  小李

1.2 search()函数

作用: 在字符串中查找指定的模式,返回第一次出现的位置

match()函数的作用是在目标字符串的起始位置开始匹配,是否符合正则表达式模式. 我们很多场景可能不一定在字符串起始位置,更多情况是在字符内搜索是否有匹配正则模式的字符串存在,这就是search()函数的存在意义了.

例1,在一段文本中查找目标字符串

import re
data = '我爱伟大的祖国,I love China,China is a great country'     #China在data字符串中的位置区间为[15,20)  半开半闭区间
pattern = 'China'
result = re.search(pattern,data)
print(result.group())

print(data[19])

China
a

例2,点号"."的使用,搜索除去换行符之外的任意字符

import re
sentence='华为是华人的骄傲'    #1,通过这个句子1可以体会点号的作用;2,search()函数会返回第一次匹配
pattern='华.'
result = re.search(pattern,sentence)   
if result:
    print(result.group())
华为

who laughs last laughs best

1.3 findall()和finditer()函数

作用:

  • findall()查询字符串中某个正则表达式全部的非重复出现情况,返回的是一个列表.
  • finditer()返回的是一个迭代器,所以相比findall()更加节省内存
import re
sentence='华为是华人的骄傲'
pattern = '华.'
result = re.findall(pattern,sentence)
print(result)
['华为', '华人']
import re
sentence = '华为是华人的骄傲'
pattern = '华.'
result = re.finditer(pattern,sentence)
print(type(result))
<class 'callable_iterator'>

1.4 group()和groups()方法

作用: 匹配对象的两个方法

  • 匹配对象: match()或者search()成功调用后返回的对象

  • 子组: 圆括号对匹配模式的各个部分进行分组和提取操作,子组可以带来的方便是,不用通过match之后,再来对特定字符串进行抽取

  • group(): 返回整个匹配对象或者返回特定的子组

  • groups(): 返回一个包含唯一或者全部子组的元组

  • 如果没有子组的要求,那么当group()仍然返回整个匹配时,groups()返回一个空元组.

例1,无子组的模式返回使用group()匹配对象

import re
pattern = 'a'
data = 'abcd'
result = re.match(pattern,data)
print(result)
print(result.group())
print(result.groups())
<re.Match object; span=(0, 1), match='a'>
a
()
import re
pattern = '(华.)\w(华.)'
sentence = '华为是华人的骄傲'
result = re.search(pattern,sentence)
print(result)
print(result.group())  #返回整个匹配对象
print(result.group(0)) #返回整个匹配对象
print(result.group(1)) #返回子组1
print(result.group(2)) #返回子组2
print(result.groups()) #返回包含所有子组的元组
<re.Match object; span=(0, 5), match='华为是华人'>
华为是华人
华为是华人
华为
华人
('华为', '华人')

1.5 compile()函数

作用: 编译正则表达式

import re
pattern = '(华.)\w(华.)'
sentence = '华为是华人的骄傲'
compiled_pattern = re.compile(pattern)  #<class 're.Pattern'>
print(type(compiled_pattern))
# result = re.match(compiled_pattern,sentence)   #(-1-)这样做,
result = re.match(pattern,sentence)       # (-2-)<class 're.Match'>
print(result)#(-1-)(-2-)得到的结果都是一样的,但是在多次用到compiled_pattern的时候,会节省了编译pattern的这个过程
<class 're.Pattern'>
<re.Match object; span=(0, 5), match='华为是华人'>

1.6 sub()和subn()函数

作用: 实现搜索和替换(找到目标字符串,然后替换掉)

sub()完成替换,返回一个被替换完成之后的字符串

subn()完成替换,还返回被替换的数量,字符串和数组,组成元组返回

import re
sentence = 'Java是很受欢迎的编程语言'
pattern = '[a-zA-Z]+'   # [字符集范围]   " + "代表: 前面的模式出现1次以上

result = re.sub(pattern,'Python',sentence)  # 使用新的Python替代
print(result)
resultn = re.subn(pattern,'Python',sentence)
print(resultn)
Python是很受欢迎的编程语言
('Python是很受欢迎的编程语言', 1)
import re
sentence = 'Java是一门强大的语言,Go前途不错'
pattern = 'Java|Go'  # 或关系
result = re.sub(pattern,'Python',sentence)
print(result)
Python是一门强大的语言,Python前途不错

1.7 split()

作用: 实现分隔字符串

import re
data = '百度,腾讯,阿里,华为,智能天下'
pattern = ','
result = re.split(pattern,data)
print(type(result))
print(result)
<class 'list'>
['百度', '腾讯', '阿里', '华为', '智能天下']

(二) 正则表达式的知识点汇总

介绍正则的知识点,用于编辑正则表达式,

2.1 正则模式中的字符

  • 最简单的,任意一个字符串都是一个正则表达式的模式(但是这样的通用性不强,只能匹配一个特定字符串,没有什么意义)

  • 匹配一定范围内的单个字符1[abc]: 中括号里面的内容即"或"的关系

  • 匹配一定范围内的单个字符2[a-c]: 使用连接符,代表范围,[a-z][0-9]

  • 代表单个字符的特殊符号:

    1. "."点号: 匹配任意字符(字母,数字,特殊字符,但是换行符除外)

    2. \w: 匹配任意字母,数字(比上面的"."少了特殊字符)

    3. \d: 匹配任意十进制数字(比上面的\w少了字母)

    4. \s: 匹配空白

    5. \b: 匹配边界

    6. ^: 匹配开始

    7. $: 匹配结尾

    8. 注意: 如果要在模式中匹配上面出现的特殊字符,例如: ".","","^","$",需要使用转义字符:\

2.2 正则中频数的表示

概括的表示频数

  • *: 代表匹配0次或者多次
  • +: 代表匹配1次或者多次
  • ?: 代表匹配0次或者一次

精确的表示频数

  • {n}: 代表前面的模式出现n次
  • {m,n}: 代表前面的模式出现m到n次之间

2.3 其它重要知识点

分组

模式中被"()"括起来的内容,是可以被提取的,Python以及各种语言实现了这种功能,group()

模式的逻辑或与否定

  1. "|" 代表两个模式的或关系

    例如: bat|tmd 可以匹配:bt,bm,bd,at,am,ad,tt,tm,td

    同: [bat][tmd]

  2. "^" 除匹配字符串的开始之外,如果用在[]中,代表否定的意思

    例如: [\d]代表的是一个十进制数,[^\d]代表除十进制数之外的其它模式

正则表达式的扩展表示法

2.4 转义字符与原始字符串

转义字符: \ 在字符串中,转义字符用于输出一些特殊字符,例如:\b,代表的是退格,\n代表换行,\t代表制表符,本质上,字符串的转义字符,是为了打印准备的,所以我们暂且定义: 字面量和打印量

原始字符串: 把字母"r"放在字符串开头,代表这是一个原始字符串,它的作用在于消除字符串和正则表达式之间各自关于转义的歧义,例如: \b在正则中表示边界

在cmd窗口里面,定义一个字符串data = '\',输入data与print(data)得到的是不一样的结果,前者是'\',后者是'',这就是字面量和打印量的区别

这个时候再来解释转义在字符串中和正则中的歧义问题就明了了

data = 'ab\cd' # 现在需要要匹配出data中的\怎么处理

首先,data的字面量,也就是字符串的真实值看似是'ab\cd',其实,你用cmd窗口,直接输出data而不是print(data),会发现,字符串的字面显示: ab\cd
所以要匹配出来data的'',pattern要如何写呢?

pattern1 = ''

pattern2 = '\'

pattern3 = '\\'

结果是第三个,首先pattern是一个字符串,虽然要交给正则表达式引擎去解析,但是终归是一个字符串,那么就要经过字符串的转义处理,第一个语法错误,这个''首先转义了结尾的"'",字符串没有结尾了;第二个,'\'是正确的字符串,经过字符串转义后,字面量是\,传递给正则引擎的时候和打印的时候一样,是'',但是真实的data字面量是'\',肯定匹配不到,于是只能用第三种

小马哥正在为Python的所有常见知识进行汇总, 更会有大量实战项目
点击--> 全栈工程师养成---Python内容导航页 <--查看所有Python内容

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

推荐阅读更多精彩内容