正则表达式

匹配字符串内容的一种规则,可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。

正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。

元字符

 

   匹配除换行符以外的任意字符  

\w

   匹配字母或数字或下划线

\s

   匹配任意的空白符

\d

   匹配数字

\n

   匹配一个换行符

\t

   匹配一个制表符

\b

   匹配一个单词的结尾

^

   匹配字符串的开始

$

   匹配字符串的结尾

\W(大写)
匹配非字母或数字或下划线
\D(大写)
匹配非数字
\S(大写)
匹配非空白符
a|b
匹配字符a或字符b
()
匹配括号内的表达式,也表示一个组
[...]
匹配字符组中的字符
[^...]
匹配除了字符组中字符的所有字符
\r
匹配一个回车符
\f
匹配一个换页符

 

 

量词

请注意,限定符出现在范围表达式之后。因此,它应用于整个范围表达式

量词
用法说明
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次

*、+限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个?就可以实现非贪婪或最小匹配。

 

*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复
?? 重复0次或1次,但尽可能少重复
{n,m}? 重复n到m次,但尽可能少重复
{n,}? 重复n次以上,但尽可能少重复

例如: .*?的用法

. 是任意字符
* 是取 0 至 无限长度
? 是非贪婪模式。
合在一起就是 取尽量少的任意字符,一般不会这么单独写,他大多用在:
.*?x

就是取前面任意长度的字符,直到一个x出现

 

字符组:[ ]   在同一位置可能出现的各种字符组成一个字符组。字符可以是数字、字母或者下划线。需要从小到大依次排列 。

注:字符组只输出一个字符,它是一个范围

例如:[0-9] :0到9内的一个数字

           [A-a]:A到a内的一个字符,根据ascii

          [0-9x]: 0到9内的一个数字 以及x

转义符

在正则表达式中,有很多有特殊意义的是元字符,比如\d和\s等,如果要在正则中匹配正常的"\d"而不是"数字"就需要对"\"进行转义,变成'\\'。

在python中,无论是正则表达式,还是待匹配的内容,都是以字符串的形式出现的,在字符串中\也有特殊的含义,本身还需要转义。所以如果匹配一次"\d",字符串中要写成'\\d',那么正则里就要写成"\\\\d",这样就太麻烦了。这个时候我们就用到了r'\d'这个概念,此时的正则是r'\\d'就可以了。

正则 待匹配字符 匹配
结果
说明
\d \d  False
因为在正则表达式中\是有特殊意义的字符,所以要匹配\d本身,用表达式\d无法匹配
\\d \d  True
转义\之后变成\\,即可匹配
"\\\\d" '\\d'  True
如果在python中,字符串中的'\'也需要转义,所以每一个字符串'\'又需要转义一次
r'\\d' r'\d'  True
在字符串之前加r,让整个字符串不转义

 

re模块下的常用方法

 

import re     #导入re模块
findall
re.findall遍历匹配,可以获取字符串中所有匹配的字符串,返回一个列表。
格式:re.findall(pattern, string, flags=0)
ret = re.findall('e', 'hello everyone') # 返回所有满足匹配条件的结果,放在列表里

print(ret) #结果 : ['e', 'e','e','e']

 

search:re.search函数会在字符串内查找模式匹配,只要找到第一个匹配然后返回,如果字符串没有匹配,则返回None。

re.search(pattern, string, flags=0)

ret = re.search('e', 'hello everyone').group()

print(ret) #结果 : 'e' # 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。

 

match:决定RE是否在字符串刚开始的位置匹配。

:这个方法并不是完全匹配。当pattern结束时若string还有剩余字符,仍然视为成功。想要完全匹配,可以在表达式末尾加上边界匹配符'$'

格式 re.match(pattern, string, flags=0) pattern表示正则表达式,string表示要匹配的字符串

ret = re.match('e', 'hello everyone').group() # 和search一样,不过是在字符串开始处进行匹配

print(ret) #结果 : 'e'

 

split:按照能够匹配的子串将string分割后返回列表

  格式:

  re.split(pattern, string[, maxsplit])

  maxsplit用于指定最大分割次数,不指定将全部分割

ret = re.split('[ab]', 'abcd') # 先按'a'分割得到'''bcd',在对'''bcd'分别按'b'分割 print(ret) # ['', '', 'cd']

 

sub:使用re替换string中匹配的子串后返回替换后的字符串

格式:re.sub(pattern, repl, string, count) repl表示用什么替换,count表示替换的个数

ret = re.sub('\d', 'H', '1ello world', 1)#将数字替换成'H',参数1表示只替换1个 print(ret) #hello world

 

subn:返回替换次数 ret = re.subn('\d', 'H', '1ello world 1')#将数字替换成'H',返回元组(替换的结果,替换了多少次) print(ret)

 

compile:编译正则表达式对象

obj = re.compile('\d{3}') #将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字

ret = obj.search('abc123eeee') #正则表达式对象调用search,参数为待匹配的字符串

print(ret.group()) #结果 : 123

 

finditer:搜索string,返回一个顺序访问每一个匹配结果(Match对象)的迭代器。

找到 RE 匹配的所有子串,并把它们作为一个迭代器返回

格式:re.finditer(pattern, string, flags=0)

import re
ret = re.finditer('\d', 'ds3sy4784a')   #finditer返回一个存放匹配结果的迭代器
print(ret)  # <callable_iterator object at 0x10195f940>     得到可被调用的迭代器
print(next(ret).group())  #查看第一个结果
print(next(ret).group())  #查看第二个结果
print([i.group() for i in ret])  #查看剩余的左右结果

()在findall的优先级查询

 

import re

ret = re.findall('123(ABC)', '123ABC456')
print(ret)  # ['ABC']     这是因为findall会优先把匹配结果组里内容返回,如果想要匹配结果,取消权限即可

ret = re.findall('123(?:ABC)', '123ABC456')     #在括号内加入 ?:   就可以取消权限
print(ret) # [
'123(ABC)']

 

()在split的应用

 

# import re
# f=re.split('\d','what1are2you3doing')
# print(f)
['what', 'are', 'you', 'doing']

# import re
# f=re.split(('\d'),'what1are2you3doing')
# print(f)
['what', '1', 'are', '2', 'you', '3', 'doing'] #当正则表达式加上括号时,被匹配的项被保留了下来

 

import re

ret = re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")  
print(ret.group('tag_name')) #结果 :h1
print(ret.group(1)) #结果 :h1 print(ret.group()) #结果 :<h1>hello</h1>


#这里正则表达式和带匹配的字符串时一一对应的
#还可以在分组中利用
?p<name> 的形式给分组起名字
#获取的匹配结果可以直接用group(
'名字')拿到对应的值.                                             
#当然也可以根据括号的序号来进行求值,序号从左到右数,从1开始

 

posted @ 2018-01-09 17:02  排骨南  阅读(172)  评论(0编辑  收藏  举报