正则表达式总结及python的re模块常用函数介绍

一、正字表达式简介

概念:正则表达式,又称规则表达式(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。

正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。正则表达式是一种文本模式,模式描述在搜索文本时要匹配的一个或多个字符串。(百度百科)

说白了就是用来匹配字符的一个模式,满足该模式的表示匹配上了,就能够做查询、获取、替换等字符操作了。

(一)正则表达式元字符

通配符 含义 正则示例 匹配结果
reg1 | reg2 匹配正则表达式reg1或reg2 foo | bar foo
+ 匹配1次或者多次前面出现的正则表达式 [a-z]+ aasx
? 匹配0次或者1次前面出现的正则表达式 first? first
{N} 匹配N次前面出现的正则表达式 *.c{2} first.c abc.c
{M,N} 匹配M~N次前面出现的正则表达式 *.c{0,1} one.c
. 匹配任何字符(\n除外) a.a abc
^ 匹配字符串起始部分 ^a ab…
$ 匹配字符串终止部分 .txt$ a.txt
* 匹配0次或者多次前面出现的正则表达式 a* aaaaa
[…] 匹配来自字符集的任意单个字符 [abc] b
[^…] 不匹配次字符集中任意单个字符 [^0-9] a
(*|+|?|{})? 匹配上面频繁出现符号的非贪婪版 (*|+|?|{})? ({})
(…) 匹配封闭的正则表达式,然后另存为子组 ([0-1][0-9])? 12
\d 匹配任何十进制数字 \d.txt 1.txt
\w 匹配任何字母数字字符 \w{2}txt 1.txt
\s 匹配任何空格字符 a\sb a b
\b 匹配任何单词边界 The\bdog The dog
\N 匹配已保存的子组 ([0-9])\1 1
\. "\"是转义字符,用在特殊字符前 a.txt a.txt

等价匹配:

  • ?,*,+,\d,\w 都是等价字符
  • ?等价于匹配长度{0,1}
  • *等价于匹配长度{0,}
  • +等价于匹配长度{1,}
  • \d等价于[0-9]
  • \D等价于[^0-9]
  • \w等价于[A-Za-z_0-9]
  • \W等价于[^A-Za-z_0-9]

**贪婪模式:**正则表达式一般趋向于最大长度匹配,也就是所谓的贪婪匹配。如上面使用模式p匹配字符串str,结果就是匹配到abcaxc(ab.*c)

**非贪婪模式:**就是匹配到结果就好,就少的匹配字符。如上面使用模式p匹配字符串str,结果就是匹配到abc(ab.*c)。一般在某个模式后面跟上?表示非贪婪

(二)常用正则表达式

在这里插入图片描述

二、python的re模块

python的re模块就是用来用正则表达式的方式封装了几个使用的函数

  • match(pattern, string, flags = 0)使用带有可选标记的正则表达式的模式来匹配字符串。如果匹配成功,返回匹配对象,否则返回None。 从字符串头部开始匹配
import re

content = 'The 123456 is my one phone number.'
print(len(content)) #字符串长度
result = re.match(r'^The\s\d+\s\w*', content) #使用match匹配, 第一个参数为正则表达式, 第二个为要匹配的字符串
print(result)
print(result.group()) #输出匹配内容
print(result.span()) #输出匹配内容的位置索引

输出:
34
<_sre.SRE_Match object; span=(0, 13), match='The 123456 is'>
The 123456 is
(0, 13)
  • search(pattern, string ,flags = 0) 使用可选标记搜索字符串中第一次出现的正则表达式模式。如果匹配成功,则返回匹配对象,否则返回None,与match()方法不同, 不需要从头部开始匹配。
import re

content = 'Other The 123456 is my one phone number.'
result = re.search('The.*?(\d+).*?number.', content)
print(result.group())

输出:
The 123456 is my one phone number.
  • findall(pattern, string[,flags] ) 查找字符串中所有(非重复)出现的正则表达式模式,并返回一个匹配列表。 match()和search()都是返回匹配到的第一个内容就结束匹配, findall()是返回所有符合匹配规则的内容。
示例1import re

html = '''
<div id="songs-list">
<h2 class="title">歌单</h2>
<p class="introduction">歌单列表</p>
<ul id="list" class="list-group">
<li data-view="2">一路上有你</li>
<li data-view="7">
<a href="/2.mp3" singer="任贤齐">沧海一声笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="齐秦">往事随风</a>
</li>
<li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
<li data-view="5"><a href="/5.mp3" singer="程慧玲">记事本</a></li>
<li data-veiw="5">
<a href="/6.mp3" singer="邓丽君">但愿人长久</a>
</li>
</ul>
</div>
'''

result = re.findall('<li.*?href="(.*?)".*?singer="(.*?)">(.*?)</a>', html, re.S)
if result:
    print(result)
    for res in result:
        print(res[0], res[1], res[2])
        
        
输出:
[('/2.mp3', '任贤齐', '沧海一声笑'), ('/3.mp3', '齐秦', '往事随风'), ('/4.mp3', 'beyond', '光辉岁月'), ('/5.mp3', '程慧玲', '记事本'), ('/6.mp3', '邓丽君', '但愿人长久')]
/2.mp3 任贤齐 沧海一声笑
/3.mp3 齐秦 往事随风
/4.mp3 beyond 光辉岁月
/5.mp3 程慧玲 记事本
/6.mp3 邓丽君 但愿人长久

示例2import re

string="abcdefg  acbdgef  abcdgfe  cadbgfe"

#带括号与不带括号的区别
#不带括号
regex=re.compile("((\w+)\s+\w+)")
print(regex.findall(string))
#输出:[('abcdefg  acbdgef', 'abcdefg'), ('abcdgfe  cadbgfe', 'abcdgfe')]

regex1=re.compile("(\w+)\s+\w+")
print(regex1.findall(string))
#输出:['abcdefg', 'abcdgfe']

regex2=re.compile("\w+\s+\w+")
print(regex2.findall(string))
#输出:['abcdefg  acbdgef', 'abcdgfe  cadbgfe']

备注:
第一个 regex 中是带有2个括号的,我们可以看到其输出是一个list 中包含2tuple 
第二个 regex 中带有1个括号,其输出的内容就是括号匹配到的内容,而不是整个表达式所匹配到的结果。
第三个 regex 中不带有括号,其输出的内容就是整个表达式所匹配到的内容。
 
结论:findall()返回的是括号所匹配到的结果(如regex1),多个括号就会返回多个括号分别匹配到的结果(如regex),如果没有括号就返回就返回整条语句所匹配到的结果(如regex2)。所以在提取数据的时候就需要注意这个坑。
实际上是由其并不是python特有的,这是 正则 所特有的 , 任何一门高级语言使用正则都满足这个特点:有括号时只能匹配到括号中的内容,没有括号【相当于在最外层增加了一个括号】。在正则里面 “()” 代表的是分组的意思,一个括号代表一个分组,你只能匹配到"()"中的内容
  • finditer(pattern, string[,flags] ) 与findall()相同,但返回的是一个迭代器。对于每一次匹配,迭代器都能返回一个匹配对象
  • split(pattern, string, max = 0) 根据正则表达式的模式分隔符,split函数将字符串分割为列表,返回匹配列表,分割最多操作max次
  • sub()方法,去除匹配的字符
import re

content = '54abc59de335f7778888g'
content = re.sub('\d+', '', content)
print(content)

输出:
abcdefg
  • compile(pattern, flags = 0) 匹配任何可选的标记来编译正则表达式的模式,然后返回一个正则表达式对象,可以用来简化代码
import re

content1 = '2016-1-1 12:01'
content2 = '2017-1-1 12:02'
content3 = '2018-1-1 12:03'

pattern = re.compile('\d{2}:\d{2}')
result1 = re.sub(pattern, '', content1)
result2 = re.sub(pattern, '', content2)
result3 = re.sub(pattern, '', content3)
print(result1, result2, result3)

输出:
2016-1-1  2017-1-1  2018-1-1 
  • group(num=0)返回整个匹配对象,或者编号为num的特定子组
import re

content = 'The 123456 is my one phone number.'
print(len(content)) #字符串长度
result = re.match(r'^The\s(\d+)\sis', content) #使用match匹配, 第一个参数为正则表达式, 第二个为要匹配的字符串
print(result)
print(result.group()) #输出匹配内容
print(result.group(1)) #输出第一个被()包裹的特定子组
print(result.span()) #输出匹配内容的位置索引

输出:
34
<_sre.SRE_Match object; span=(0, 13), match='The 123456 is'>
The 123456 is
123456
(0, 13)
  • 修饰符re.S
import re

content = '''The 123456 is
one of my phone.
'''
result = re.match('^The.*?(\d+).*?phone.', content, re.S)
if result:
    print(result.group(1))
else:
    print('result = None')
result2 = re.match('^The.*?(\d+).*?phone.', content)
if result2:
    print(result2.group(1))
else:
    print('result2 = None')

    
输出:
123456
result2 = None
  • re.I(re.IGNORECASE)表示使匹配时,忽略大小
  • re.M(re.MULTILINE)多行匹配,影响 ^ 和 $的行为
  • re.X(re.VERBOSE)这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。

参考文章:

Python中re模块的使用

正则表达式贪婪与非贪婪模式

Python中re模块基本用法解析

python正则表达式(7)–flag修饰符、match对象属性

python re模块findall()详解

猜你喜欢

转载自blog.csdn.net/lwcaiCSDN/article/details/88416487