python----正则表达式re库

正则表达式是干什么的

使用正则表达式就是为了从一大串子字符串中获取你想要的那部分,如果你明确的知道你想要的就是字符串"wjg946"那么就不需要使用一些高级的匹配用法,其实如果你知道了你想要的字符串就是"wjg946"那还匹配什么,所一般都是只知道所需字符串的部分特征,要做的就是根据这些特征把想要的字符串从大量文本中揪出来。

python中使用正则表达式一般都是使用re库,所以写这个。

基本知识

1、匹配规则
d w s

.匹配任意1个字符(除了换行符\n)
[ ]匹配 [ ] 中列举的字符
\d匹配数字,也就是0-9
\D匹配非数字,也就是匹配不是数字的字符
\s匹配空白符,也就是 空格、换行符、制表符
\S匹配非空白符
\w匹配单词字符, a-z, A-Z, 0-9, _也就是字母、数字、下划线
\W匹配非单词字符

2、匹配数量规则

*匹配前一个字符出现0次多次或者无限次,可有可无,可多可少
+匹配前一个字符出现1次或则无限次
?匹配前一个字符出现1次或者0次
{m}匹配前一个字符出现m次
{m,}匹配前一个字符至少出现m次
{m,n}匹配前一个字符出现m到n次

3、限定匹配的位置

^匹配字符串开头
$匹配字符串结尾

^意味着这个字符串必须从开头就开始满足匹配条件,不然整个字符串后面的就看了,
$同理
^和$同时使用意味着整个字符串必须匹配该模式,只匹配字符串的某个子集是不够的。

regex =re.compile(r"^hi$")
regex.search("hi").group()
#hi
regex.search("hih").group()
#None

4、建立自己的字符分类
有时候\d \s \w范围太广了,需要自己定义一个就可以使用[ ],代表一个字符,当某个字符属于括号里面的某一个就符合,如果是[^ ]就是不包括里面的,即剔除。

regex =re.compile(r"[123]+")
regex.search("237123").group()
#'23'
regex =re.compile(r"[123]{3}")
regex.search("237123").group()
#'123'
regex =re.compile(r"[^123]+")
regex.search("237123").group()
#'7'

还可以写[A-Za-z0-9]

常用函数

1、re.compile()
传入一个字符串,作为正则表达式,返回一个Regex对象(就是Regex模式、匹配模式)。

2、Regex.search()
向匹配模式中传入一个需要查找的字符串,在该字符串中寻找符合条件的所有匹配,如果没有,返回None。返回的对象类型是Match

3、Match.group()
Match.group()返回实际匹配的字符串文本。

import re
regex = re.compile(r"\d{11}")
match = regex.search("我的电话号码是17854339997")
result = match.group()
print(result)
#17854339997

高级用法:
1、分组
如果想要将匹配到的字符串分成几个部分,分别取出来,就需要在构造匹配模式的时候使用括号创建分组。
然后在match.group()中传入参数,0或者不传参代表返回整个文本,1对应第一组,2对应第二组

import re
regex = re.compile(r"(\d{3})(\d{8})")
match = regex.search("我的电话号码是17854339997")
if match:#避免没有找到,返回None,也会执行
    result = match.group(1)
    print(result)
else:
    print("NOT FOUND")
#178    

2、用管道同时生成多种匹配模式
字符|称为管道,在构造匹配模式时,可以同时生成多个,在匹配字符串时,只要妈祖多个匹配模式中的一种即可,但是search()只会返回一个Match对象,里面只有一个满足条件的字符串,前面说的分组,是在这一个字符串的进一步分组。

import re
regex = re.compile(r"(\d{3})(\d{8})|电话")
match = regex.search("我的电话号码是17854339997")
if match:#避免没有找到,返回None,也会执行
    result = match.group()
    print(result)
else:
    print("NOT FOUND")
#电话    

3、贪心匹配和非贪心匹配
在hihihihihi字符串中,(hi)+可以把整个字符串都匹配到,这就是贪心匹配,再对比非贪心匹配,非贪心匹配会得到hi一个就够了,匹配模式是(hi)?
所谓贪心与非贪心只是针对一些可以匹配到多个的情况,例如 **+ 和 * 和 {1,9}**这几个默认都是贪心的,变成非贪心就只需要在后面加一个问号?

regex_tan = re.compile(r"(hi)+")
regex_butan = re.compile(r"(hi)+?")
match_tan = regex_tan.search("hihihihihi")
print(match_tan.group())
#hihihihihi
match_butan = regex_butan.search("hihihihihi")
print(match_butan.group())
#hi

如果匹配模式写的是(hi)*?那么由于非贪婪,这个正则表达式会匹配到空字符串,但也不是None

4、regex.findall()
regex.search()只能从字符串中找出一个匹配对象,而这个regex.findall()可以匹配到字符串中所有满足要求的。但是与前者不同的地方是,findall()返回的是字符串列表而不是match对象,所以也就不能使用group()方法,因为group()对于分组之后取第几组比较友好,那么对于findall()中分组的情况该怎么解决呢?如果匹配模式进行了分组,那么findall()返回的就是元组的列表

regex = re.compile(r"(\d{3})(\d{8})")
l = regex.findall("我的电话是17856786533,小虎的电话是18892736300")
if l:
    print(l)
#[('178', '56786533'), ('188', '92736300')]    

5、.*可以匹配任何长度的字符(换行符处会截断),.*?就是一种很好的承接后面部分的东西(不好解释),如果让.也可以匹配换行符,需要在compile()函数后面跟上一个re.DOTALL

noNewLineRegex = re.compile(r".*")
noNewLineRegex.search("Hello\nHow are you?").group()
#'Hello'

newLineRegex = re.compile(r".*",re.DOTALL)#	.可以匹配换行符了
newLineRegex.search("Hello\nHow are you?").group()
#'Hello\nHow are you?'

6、不区分大小写的匹配
向re.compile()中传入re.I或者re.IGNORECASE可以不区分大写来匹配

regex = re.compile(r"hello",re.I)
regex.search("HELLO\nHow are you?").group()
#'HELLO'

匹配演示

注意区别

regex = re.compile(r"[^电话]")
l = regex.findall("我的电话是17856786533,小虎的电话是18892736300")
if l:
    print(l)
['我', '的', '是', '1', '7', '8', '5', '6', '7', '8', '6', '5', '3', '3', ',', '小', '虎', '的', '是', '1', '8', '8', '9', '2', '7', '3', '6', '3', '0', '0'] 

regex = re.compile(r"[^电话]*")
l = regex.findall("我的电话是17856786533,小虎的电话是18892736300")
if l:
    print(l)   
['我的', '', '', '是17856786533,小虎的', '', '', '是18892736300', '']   

注意区别

regex = re.compile(r"(电话)+")
l = regex.findall("我的电话是17856786533,小虎的电话是18892736300")
if l:
    print(l)
['电话', '电话']    

regex = re.compile(r"(电话)*")
l = regex.findall("我的电话是17856786533,小虎的电话是18892736300")
if l:
    print(l)
['', '', '电话', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '电话', '', '', '', '', '', '', '', '', '', '', '', '', '']    

使用sub()方法替换

Regex.sub(“替换的补料”,“检索的字符串”)
将字符串中满足条件的字串进行替换,返回新的字符串。

regex = re.compile("\d{11}")
str = regex.sub("***","我的电话是17856786533")
print(str)
#我的电话是***

如果替换的补料想使用匹配到的文本本身的一部分,可以在sub()第一个参数中输入\1,\2,\3这里的数字代表匹配模式里的分组中的第几组,从1开始。
不要忘记在第一个参数前面加r,不然会出错。

regex = re.compile(r"(\d{3})\d{4}(\d{4})")
str = regex.sub(r"\1****\2","我的电话是17856786533,你呢?")	#加r
print(str)
#我的电话是178****6533,你呢?

使用re.split()分割字符串

相比于使用字符串的spilt()方法切割字符串,re.split()更加的灵活,比如对字符串"hu j, dd, jl"分割,按照逗号分割,不考虑逗号的数量,例如有两个连续的逗号,他们两个之间不应该分开。

str = "hu j,, dd, jl"
lst = str.split(",")
print(lst)
#['hu j', '', ' dd', ' jl']		#列表中有一个空字符串

"""使用re正则表达式切分,更加灵活"""
regex = re.compile(r"[,]+")
lst = re.split(regex,str)
print(lst)
#['hu j', ' dd', ' jl']

复杂的正则表达式

如果正则表达式复杂之后,很容易致使编程人员看不明白,但是由于表达式分布在同一行,所以不能直接加注释。
向re.complie()中传递re.VERBOSE参数,使得其忽略空白符和注释。

re.complie(r"""(
    (\d{3}|\(\d{3}\))?			#area code
    (\s|-\\.)?					#separator
    \d{3}						#first 3 digtis
    (\s|-|\.)					#separator
    \d{4}						#last 4 digits
    (\s*(ext|x|ext.)\s*\d{2,5})?#extension
    )""",re.VERBOSE)

例子

编写一个正则表达式匹配句子,他的第一个单词是Alice、Bob、Cindy第二个单词是eats、pets、throws第三个单词是apples、cats、baseballs

regex = re.compile("(Alice|Bob|Cindy) (eats|pets|throws) (apples|cats|baseballs)")

print(regex.search("Alice eats apples").group())
print(regex.search("Bob pets cats").group())
print(regex.search("Cindy throws baseballs").group())
print(regex.search("Alice throws cats").group())
Alice eats apples
Bob pets cats
Cindy throws baseballs
Alice throws cats

这种用法还挺有意思的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值