您的位置:首页 > 其它

正则表达式

2017-12-30 22:11 239 查看
1 正则表达式是什么

Regular Expression, 又称规则表达式。
正则表达式,就是用事先定义好的一些特定字符(组合),组成一个“规则字符串”,这个“规则字符串”用来描述了一种字符串的匹配模式(pattern)。
正则的作用:可以用来检查一个串是否含有某种数据、将匹配的数据替换或者取出


2 在Python中需要通过正则表达式对字符串进行匹配的时候,可以使用一个模块,名字为re

2.1 re模块的使用过程:

#coding=utf-8

# 导入re模块
import re

# 使用match方法进行匹配操作
result = re.match(正则表达式,要匹配的字符串)
# 如果上一步匹配到数据的话,可以使用group方法来提取数据
result.group()
# 如果没有匹配 则result是None

result = re.search(正则表达式,要匹配的字符串)

# 如果上一步匹配到数据的话,可以使用group方法来提取数据
result.group()
# 如果没有匹配 则result是None


2.2re模块示范例子:


#coding=utf-8

import re

result = re.search(r"itcast","itcast.cn")
result.group()
result = re.match(r"itcast","itcast.cn")
result.group(

运行结果为:itcast


3 匹配单个字字符 功能

.匹配任意1个字符(除了\n)

[ ]匹配[ ]中列举的字符

\d匹配数字,即0-9

\D匹配非数字,即不是数字

\s匹配空白,即 空格,tab键

\S匹配非空白

\w匹配单词字符,即a-z、A-Z、0-9、_

\W匹配非单词字符

4 匹配多个字符

字符 功能

* 匹配前一个字符出现0次或者无限次,即可有可无 \d* 等价于\d{0,}

+ 匹配前一个字符出现1次或者无限次,即至少有1次 \d+ 等价于\d{1,}

? 匹配前一个字符出现1次或者0次,即要么有1次,要么没有 \d?等价于\d{0,1}

{m} 匹配前一个字符出现m次

{m,n} 匹配前一个字符出现从m到n次配开头和结尾

字符    功能
^    匹配字符串开头,开始位置,
虽然match自带匹配开始的属性 但是为了正则的语义完整 建议也加上^

$   匹配字符串结尾,结束位置
匹配的是结束位置  而不是数据


6 匹配分组

字符          功能
|          匹配左右任意一个表达式
(ab)       将括号中字符作为一个分组
\num       引用分组num匹配到的字符串
(?P<name>) 分组起别名
(?P=name)  引用别名为name分组匹配到的字符串

详解:
目的 -- 在正则中使用() 将感兴趣的数据从整体中提取出来 放到分组存储
等整体匹配成功返回的结果对象中 .group(分组编号)就可以获取对应分组中数据了

group(0) == group()  就是正则表达式整体匹配的结果
用户的分组编号从1开始

()  表示匹配数据并放入分组
.group(分组编号)就可以获取对应分组中数据了

|   表示匹配|左边或者右边的正则表达式
(|) 表示匹配分组中| 左边或者右边的表达式 并且放入分组中

eg:<html>hh</html>  --- <标签名>数据</标签名>
判断左边的标签和右边的标签名是否一致  如果一致则提取中的数据
引用分组的方式
目的  在正则的某个位置想要使用前面某个分组的数据进行匹配
使用形式: \分组编号
<html><h1>www.itcast.cn</h1></html>
re.match(r"(<\w+)><(\w+)>(.*)</\2></\1>","<html><h1>www.baidu.com</h1></html>").group(1)

有名分组
在匹配分组的时候 使用一个名字 而不直接使用下标
设置分组名称               (?P<name>)
引用某个名称的分组的数据   (?P=name)


7 re模块函数

7.1

match() 从头开始匹配  如果某个字符不能满足匹配规则 将匹配失败 返回None
直到匹配完成 将匹配结果放入匹配结果对象中,从匹配结果对象中获取到匹配结果,matchobj.group()

result = re.match(正则, 数据)
if result:
print(result.group())
else:
print("匹配失败")


7.2


search() 从头开始查找 如果某个字符不能满足匹配规则 将继续往后面查找 并尝试继续匹配
如果查找完 都没有匹配上 则返回None
如果匹配成功 将匹配结果放入匹配结果对象中,从匹配结果对象中获取到匹配结果,matchobj.group()

result = re.search(正则,数据)
if result:
print(result.group())
else:
print("匹配失败")

eg:匹配出文章阅读的次数
#coding=utf-8
import re

ret = re.search(r"\d+", "阅读次数为 9999")
ret.group()
运行结果:'9999'


8 re模块高级用法

8.1


findall(正则,数据)
查找数据中所有 符合正则规则的 数据 通过列表返回

eg:需求:统计出python、c、c++相应文章阅读的次数
#coding=utf-8
import re

ret = re.findall(r"\d+", "python = 9999, c = 7890, c++ = 12345")
print(ret)
运行结果:['9999', '7890', '12345']


8.2


sub(正则,替换的数据, 被替换的数据)
将匹配到的数据进行替换
返回值返回 被替换之后的数据结果 字符串 源字符串不变

参数2还可以是一个函数的名字
这个函数需要满足一下几个条件才可以被正则调用
必须要有一个参数 -----  通过这个参数将正则的匹配对象传递进去
必须要有一个返回值 ----- 通过返回值 返回替换的数据

需求:将匹配到的阅读次数加1

方法1:
#coding=utf-8
import re

ret = re.sub(r"\d+", '998', "python = 997")
print(ret)
运行结果:python = 998

方法2:
#coding=utf-8
import re

def add(temp):
strNum = temp.group()
num = int(strNum) + 1
return str(num)

ret = re.sub(r"\d+", add, "python = 997")
print(ret)
运行结果:python = 998


8.3


split(正则, 数据)
split 根据匹配进行切割字符串,并返回一个列表
正则是描述切割的规则
返回值就是切割之后的列表

eg:切割字符串“info:xiaoZhang 33 shandong”

#coding=utf-8
import re

ret = re.split(r":| ","info:xiaoZhang 33 shandong")
print(ret)
运行结果:

['info', 'xiaoZhang', '33', 'shandong']


9 贪婪模式与非贪婪模式

Python里数量词默认是贪婪的,总是尝试匹配尽可能多的字符;
在满足整体匹配的情况下 贪婪会尽可能的多匹配 非贪婪会尽可能少的匹配
如果想要让python使用非贪婪模式 在量词"*","?","+","{m,n}"等之后加上?

贪婪尽可能多,非贪婪尽可能少。 贪婪和非贪婪必须有一个前提就是满足整体匹配结果。

eg:
>>> s="This is a number 234-235-22-423"
>>> r=re.match(".+(\d+-\d+-\d+-\d+)",s)
>>> r.group(1)
'4-235-22-423'

>>> r=re.match(".+?(\d+-\d+-\d+-\d+)",s)
>>> r.group(1)
'234-235-22-423'

>>> re.match(r"aa(\d+)","aa2343ddd").group(1)
'2343'
>>> re.match(r"aa(\d+?)","aa2343ddd").group(1)
'2'
>>> re.match(r"aa(\d+)ddd","aa2343ddd").group(1)
'2343'
>>> re.match(r"aa(\d+?)ddd","aa2343ddd").group(1)
'2343'

In [36]: res = re.search("^(\w+)_(\w+?)$","hello_world")
In [37]: res.group()
Out[37]: 'hello_world'
In [38]: res.group(1)
Out[38]: 'hello'
In [39]: res.group(2)
Out[39]: 'world'


Python中字符串前面加上 r 表示原生字符串

自动会对字符串中的\进行转义  ---- > 解决在匹配多\的情况的困扰

>>> mm = "c:\\a\\b\\c"
>>> mm
'c:\\a\\b\\c'
>>> print(mm)
c:\a\b\c
>>> re.match("c:\\\\",mm).group()
'c:\\'
>>> ret = re.match("c:\\\\",mm).group()
>>> print(ret)
c:\
>>> ret = re.match("c:\\\\a",mm).group()
>>> print(ret)
c:\a
>>> ret = re.match(r"c:\\a",mm).group()
>>> print(ret)
c:\a
>>> ret = re.match(r"c:\a",mm).group()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'
>>>

与大多数编程语言相同,正则表达式里使用"\"作为转义字符,这就可能造成反斜杠困扰。
假如你需要匹配文本中的两个字符"\w",python语言层级会先尝试对\w进行转义 (比如\n\r\v\t\f\e\0等) 如果不属于ASCII码中的转义字符就会'\w'自动转义为两个反斜杠 \\w。
那么 使用编程语言的正则表达式里将需要4个反斜杠"\\": 对于python语言来讲会将两个连续的‘\’解释为一个\
前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。
Python里的原生字符串很好地解决了这个问题,有了原生字符串,再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。

>>> ret = re.match(r"c:\\a",mm).group()
>>> print(ret)
c:\a
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: