正则表达式
正则表达式:又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。
是一种特殊的字符序列,是用于处理字符串的强大工具
使用简洁的字符串表达式,来匹配这些信息
1.不同编程语言对应的工具
编程语言 | 正则表达式工具 |
---|---|
Java | util.regrex包 |
Linux / Unix | grep awk sed 等 |
Python | re库 |
C/C++ | GNU Regex Library, Boost.Regex, PCRE, PCRE++ |
2.工作流程
3.组成
1.原义(正常)文本字符
2.元字符
元字符 | 说明 |
---|---|
. | 任意字符 |
[] | 匹配内部的任意字符或子表达式 |
* | 匹配前面字符或子表达式0次或多次 |
+ | 匹配前一个字符或子表达式1次或多次 |
+? | 惰性匹配上一个 |
? | 匹配前一个字符或子表达式0次或1次重复 |
{m,n} | 匹配前一个字符或子表达式至少m次至多n次 |
^ | 匹配字符串开头 |
$ | 匹配字符串结束 |
\d | 匹配任意数字 |
例子:
如身份证:(^\d{15}$ )|(^\d{17}([0-9]|X)$)
(匹配字符串开始 匹配任意数字15位 结束)或(匹配字符串开始 匹配任意数字17位 和0-9或X间任一位字符 结束)
4. 分组
使用正则表示是匹配重读的单字符,只需在字符后面加上相应的二元字符
若要匹配重复的字符串,使用小括号()吧目标字符串包裹起来,如(abc)? 可以匹配0个或多个字符串abc
分组可以分为两种形式:捕获组和非捕获组
1.捕获
·小括号包起来的表达式去匹配字符串,匹配的结果可以在后续的匹配过程中使用
·吧表达式中的括号进行编号,从左到右,以左括号出现的前后顺序为准,第一个出现的分组组号为1
·组号0表示正则表达式整体
如正则表达式:(\d{4})-(\d{2})-(\d\d) 匹配2017-04-19
编号 | 捕获组 | 匹配内容 |
---|---|---|
0 | (\d{4})-(\d{2})-(\d\d) | 2017-04-19 |
1 | (\d{4}) | 2071 |
2 | (\d{2})-(\d\d) | 04-19 |
3 | (\d\d) | 19 |
代码展示:
#正则表达式 捕获
import re
n = re.search(r'^(\d{3,4}-)?(\d{7,8})$','020-82228888')
print(n.group(0)) #(\d{3,4}-)?(\d{7,8})
print(n.group(1)) #(\d{3,4}-)
print(n.group(2)) #?(\d{7,8})
结果:
020-82228888
020-
82228888
2.非捕获组
·非捕获组是指以(?)开头的分组组,他不捕获文本,没有分组编号,也不针对组合进行计数
·捕获组会默认把括号里的文本捕获过来一供下次使用。如果只需要正则匹配,没有额外需求,使用非捕获组可以完成任务,降低资源消耗
如匹配0-100范围的整数
捕获组: ^([0-99]|100)$
非捕获组: ^(?:[0-99]|100)$
代码展示:
import re
n = re.search(r'^(?:\d{3,4}-)?(\d{7,8})$','020-82228888')
print(n.group(0))
print(n.group(1))
print(n.group(2))
结果:
020-82228888 //n.group(0)
82228888 //n.group(1)
print(n.group(2)):报错
IndexError Traceback (most recent call last)
in
----> 5 print(n.group(2))
IndexError: no such group
分析:
因为不捕获,他匹配的字符串只有两组,一个是整体的表达式(0号),一个是7位到8位的字符串(1号)
5.python 中的re库
使用re库匹配文本的一般过程:
- 使用compile函数讲正则表达式编译为pattern对象
- 使用pattern对象检索文本,获得匹配的结果(match对象)
- 使用match对象获得匹配结果的信息,进行想过操作
re库的主要函数:
1、re.compile(pattern[,flags])
- pattern:一个字符串形式的正则表达式
- flags:可选,表示匹配模式,如忽略大小写,多行模式等
函数返回的是pattern对象,主要有以下属性:
pattern:正则表达式对象,供match()、search()he findall()这三个函数使用
当匹配成功时返回一个match对象
2、re.math()
3、re.search()
4、re.findall()
代码编写:
m = re.compile(r'^(\d{3,4}-)?(\d{7,8})$')
p = m.match('020-82228888')
p.group(0)
‘020-82228888’
p = m.match('010-82228888')
p.group(0)
010-82228888
p = m.findall('010-82228888')
p
[(‘010-’, ‘82228888’)]
6.练习
1.现在有一条正文评论review需要去除其中的标点符号和特殊符号
现将完整的中文符号(包括标点符号和特殊符号)存放在了punctuation列表
请根据该列表,去除评论review中的中文符号,并将清洗结果存为review_cleaned
正误判定变量:review_cleaned
import re
review = "电池持久、屏幕看着舒服、操作简单人性。经摔、个性、桌面管理器操作简单。 没有很好的售后体系。"
pattern = "[+——!,。??、~@#¥%……&*()\s]+"
review_cleaned = re.sub(pattern,u"",review)
review_cleaned
结果输出
‘电池持久屏幕看着舒服操作简单人性经摔个性桌面管理器操作简单没有很好的售后体系’