美文网首页python编程
Python进阶1 - 正则表达式: 一文掌握正则表达式编程

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

作者: 小马哥China | 来源:发表于2019-06-06 23:50 被阅读0次

小马哥正在为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内容

相关文章

网友评论

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

    本文链接:https://www.haomeiwen.com/subject/hmvpxctx.html