re模块

一、正则表达式

(一)为什么使用正则?

字符串匹配就可以从文本中匹配出想要的字符,为什么要使用正则表达式?因为每一次匹配都要单独完成,不妨设立一个规则。

(二)正则表达式概念

(1)使用单个字符串来描述匹配一系列符合某个语法规则的字符串
(2)是对字符串处理的一种逻辑公式
(3)应用场景:处理文本和数据
(4)正则表达式过程:依次拿出表达式和文本的字符比较,如果每一个字符都能匹配成功,则匹配成功;否则失败。

一句话,正则表达式就是一套规则,而且是个字符串。

二、re模块

re模块是python中根据正则表达式规则写的一个功能或者模块。re模块!=正则表达式。正则表达式是一套规则,而re模块是根据该规则写的一个模块或者工具,通过这个工具来实现正则表达式的使用。

(一)re模块之方法

(1) match
re.match(pattern, string)
只匹配开头 。
得到一个match object.后面加group()才能打印出结果
如:

import re
a = "python" b = re.match("py", a).group() print(b)

(2) search
re.search(pattern, string, flags=0)
在一个字符串中查找匹配;
注意:只匹配一次(返回第一次成功匹配的结果)
得到一个match object.后面加group()才能打印出结果
如:

a = 'hpyt1848451thshhho577n'
b = re.search('\d+', a).group()
print(b) #1848451 后面的577不匹配

(3) findall
re.findall(pattern, string, flags=0)
匹配所有,返回列表
如:

a = 'hpyt1848451thshhho577n'
b = re.findall('\d+', a)
print(b) #["1848451", "577"]

(4)compile
re.compile(pattern, flags=0)
将正则表达式存到一个变量中,重复使用
如:

a = 'hpyt1848451thshhho577n'
res = re.compile('\d+') #res可以多次使用
b = re.findall(res, a)
print(b) #["1848451", "577"]

(5)sub
re.sub(pattern, repl, string, count=0, flags=0)
将字符串中匹配正则表达式的部分值替换为其他值
如:

a = 'hpyt1848451thshhho577n'
res = re.compile('\d+') #res可以多次使用
b = re.sub(res, '+', a)
print(b) #'hpyt+thshhho+n'

(6)split

re.split(pattern, string, maxsplit=0, flags=0)
根据匹配分割字符串,返回分割字符串组成的列表
如:

a = 'hpyt1848451thshhho577n'
res = re.compile('\d+') #res可以多次使用
b = re.split(res, a)
print(b) #['hpyt', 'thshhho', 'n']

  

(二)re模块之元字符

. ^ $ [] \

* + ? {}

(1)“.” 通配符

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

re.findall("y..o", "python")    #["ytho"]

一个.代表一个位置

(2)^

^ 匹配字符串以..开头

re.findall("^p...o", "python")    #["pytho"]

(3)$ 

$ 匹配字符串结尾

re.findall("^p(.*?)n$", "python")    #["python"]

这里加(.*?),是万能匹配,表示中间可以是任意内容。如果不加,直接写"^pn$",那么匹配不成功,只能匹配成功pn

(4)重复功能(量词部分)

a. *

* 匹配前一个字符0次或者无限次

re.findall("d*", "daddy")   #['d', '', 'dd', '', '']
re.findall("dd*", "daddy") #["d", "dd"]

匹配后,*前面的那个字符可以是空,也可以是多个字符。  

b. +

+ 匹配前一个字符1次或者无限次

re.findall("d+", "daddy")   #['d', 'dd']
re.findall("dd+", "daddy")  #["dd"] 

c. ?

? 匹配前一个字符0次或者1次

re.findall("d?", "daddy")   #['d', '', 'd', 'd', '', '']
re.findall("dd?", "daddy")  #['d', 'dd']

d. {}

{}范围自己给定

{0,}  == *

{1,} == +

{0, 1} == ?

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

{m,n}匹配前一个字符m-n次任意一种

re.findall("al{4}", "youallllll")    #['allll']

e.补充

在* 和+后加?,即*?和+?,匹配模式变为非贪婪模式。,即尽可能少匹配字符。

贪婪与非贪婪
1.从语法角度看贪婪与非贪婪 

被匹配优先量词修饰的子表达式,使用的是贪婪模式;被忽略优先量词修饰的子表达式,使用的是非贪婪模式。 

匹配优先量词包括:“{m,n}”、“{m,}”、“?”、“*”和“+”。 

忽略优先量词包括:“{m,n}?”、“{m,}?”、“??”、“*?”和“+?”。 

2.从应用角度看贪婪与非贪婪 

贪婪与非贪婪模式影响的是被量词修饰的子表达式的匹配行为,贪婪模式在整个表达式匹配成功的前提下,尽可能多的匹配;而非贪婪模式在整个表达式匹配成功的前提下,尽可能少的匹配。非贪婪模式只被部分NFA引擎所支持。 

3. 从匹配原理角度看贪婪与非贪婪 

能达到同样匹配结果的贪婪与非贪婪模式,通常是贪婪模式的匹配效率较高。 

所有的非贪婪模式,都可以通过修改量词修饰的子表达式,转换为贪婪模式。 

贪婪模式可以与固化分组结合,提升匹配效率,而非贪婪模式却不可以。
贪婪与非贪婪

 如:

#.*默认为贪婪匹配
print(re.findall('a.*b','a1b22222222b')) #['a1b22222222b']

#.*?为非贪婪匹配:推荐使用
print(re.findall('a.*?b','a1b22222222b')) #['a1b']
re.findall("al*", "youallllll")    #['allllll']     贪婪模式
re.findall("al*?", "youallllll")    #['a']       非贪婪模式

(5)[] 字符集

a.起或的作用

print(re.findall('a[+*-]b','a+b a*b a-b'))     #["a+b", "a*b", "a-b"]

[]内元字符不起作用.

b.[]内的^ 

[]内的^ 表示取反

print(re.findall('a[^+*-]b','a+b a*b a-b'))     #["a+b", "a*b", "a-b", "a=b"]   #["a=b"]

匹配不是+*-任意一个符号的那个

c. -

-表示连续中的任意一个

print(re.findall('a[0-9]b','a1b a*b a-b a=b'))       #["a1b"]
print(re.findall('a[a-z]b','a1b a*b a-b a=b aeb')    #["aeb"]
print(re.findall('a[a-zA-Z]b','a1b a*b a-b a=b aeb aEb'))    #["aeb", "aEb"]

(6)\

反斜杆\,能将元字符变为普通字符,将普通字符变为元字符。

a.\d匹配任意十进制数

b.\D匹配任意非数字字符

c.\s 匹配空白字符

d.\S 匹配非空白字符

e.\w 匹配字母数字字符

f.\W匹配非字母数字字符

(7)分组()

print(re.findall('ab+','ababab123')) #['ab', 'ab', 'ab']
print(re.findall('(ab)+123','ababab123')) #['ab'],匹配到末尾的ab123中的ab

注意,findall的结果不是匹配的全部内容,而是组内的内容,因此是ab

print(re.findall('(?:ab)+123','ababab123'))    #['ababab123']

:?让结果为匹配的全部内容。 

print(re.findall('href="(.*?)"', '<a href="http://www.baidu.com">点击</a>'))   #['http://www.baidu.com']

 (.*?)代表任意一个内容,且最后得到的结果是()内的内容。

print(re.findall('href="(?:.*?)"','<a href="http://www.baidu.com">点击</a>'))   #['href="http://www.baidu.com"']

有名分组  (?P<名字>正则表达式)

print(re.search("(?P<name>[a-z]+)", "python32def").group())     #"python"

#可通过group和名字取值
print(re.search("(?P<name>[a-z]+)", "python32def").group(“name”))     #"python"

  

 

posted @ 2020-04-02 16:03  yq055783  阅读(74)  评论(0编辑  收藏  举报