代码改变世界

学习python第十六天,正则表达式

2019-01-19 07:28  筑_梦  阅读(311)  评论(0编辑  收藏  举报

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。采取动态模糊的匹配,最大的应用是爬虫。

re 模块使 Python 语言拥有全部的正则表达式功能。

compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。

re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。

一、re.match函数

re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

re.match(pattern, string, flags=0)  pattern匹配的正则表达式,  string 要匹配的字符创    flags  标志位,用于控制正则表达式的匹配方式

匹配成功re.match方法返回一个匹配的对象,否则返回None。

例如

import re

print(re.match('www', 'www.runoob.com')) #在起始位置匹配
print(re.match('www', 'www.runoob.com').span())  # 在起始位置匹配
print(re.match('com', 'www.runoob.com'))         # 不在起始位置匹配

实例运行输出结果为:

<_sre.SRE_Match object; span=(0, 3), match='www'> #指用re.match匹配对象参数
(0, 3)#0代表匹配起始位置,3代表3个字符长度或叫跨度
None  #没有匹配到,因为起始位没有com

 

这属于精确的匹配,因为你已经明确的写出了要匹配的字符串,毫无悬念的匹配结果,而正则表达式的作用在于动态模糊的把要找的东西匹配出来,可用于pattern符号代表意义

'.'     默认匹配除\n之外的任意一个字符,若指定flag DOTALL,则匹配任意字符,包括换行
'^'     匹配字符开头,若指定flags MULTILINE,这种也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
'$'     匹配字符结尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以
'*'     匹配*号前的字符0次或多次,re.findall("ab*","cabb3abcbbac")  结果为['abb', 'ab', 'a']
'+'     匹配前一个字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 结果['ab', 'abb']
'?'     匹配前一个字符1次或0次
'{m}'   匹配前一个字符m次
'{n,m}' 匹配前一个字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 结果'abb', 'ab', 'abb']
'|'     匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 结果'ABC'
'(...)' 分组匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 结果 abcabca456c
'\A'    只从字符开头匹配,re.search("\Aabc","alexabc") 是匹配不到的
'\Z'    匹配字符结尾,同$
'\d'    匹配数字0-9
'\D'    匹配非数字
'\w'    匹配[A-Za-z0-9]
'\W'    匹配非[A-Za-z0-9]
's'     匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 结果 '\t'
'(?P<name>...)' 分组匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 结果{'province': '3714', 'city': '81', 'birthday': '1993'}

 最全的表达式:http://www.cnblogs.com/zxin/archive/2013/01/26/2877765.html

二、re.search方法

re.search 扫描整个字符串并返回第一个成功的匹配。

import re
print(re.search('www', 'www.runoob.com').span())  # 在起始位置匹配
print(re.search('com', 'www.runoob.com').span())         # 不在起始位置匹配
以上实例运行输出结果为:

(0, 3)
(11, 14)

三、不进行转义  使用 r 能够防止自动转义\t、\n

r': raw的缩写,一般用在正则表达式中,称为原始字符串,作用是将Python语法中的反斜杠转义给取消,将其设置成为一个普通的字符串。也就是说当你在定义这个字符串的时候它是什么样的,最终在输出打印的时候

   也就是什么样的,中间转义的过程python帮我们实现了。

栗子

print 'a\nb'
print r'a\nb'

结果

a
b
a\nb  #加r之后不会再将\n转化换行符,只输出原始字符创

  以后写正则表达式要习惯加上 r ,因为\n、\t没在正则表达式中出现过,所以用r自动转义;而 . 在正则表达式中出现了,所以单独转义

四 检索和替换re.sub

Python 的 re 模块提供了re.sub用于替换字符串中的匹配项。

 栗子1

phone = "2004-959-559 # 这是一个国外电话号码" 
num = re.sub(r'#.*$', "", phone)# 删除字符串中的 Python注释 
print ("电话号码是: ", num)
 
num = re.sub(r'\D', "", phone)# 删除非数字(-)的字符串 ,包括中文
print( "电话号码是 : ", num)

以上实例执行结果如下:

电话号码是:  2004-959-559 
电话号码是 :  2004959559

 栗子2

def double(matched):
    value = int(matched.group('value'))#\d+匹配连续数字为一个个的组,组的名字命名为value
    return str(value * 2)
 
s = 'A23G4HFD567'
print(re.sub('(?P<value>\d+)', double, s))

?P<value> 代表的是为group 分组添加一个分组名为group命令,全要在前面添加一个问号,如果问号没有添加,就没有命名成group   '+号',是当匹配到多个数字字符串时,将整个字符串数字*2,不是将单个数字字符*2

执行输出结果为:

A46G8HFD1134

   

re.compile 函数

compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 及findall函数使用。该函数根据包含的正则表达式的字符串创建模式对象。可以实现更有效率的匹配。在直接使用字符串表示的正则表达式进行search,match和findall操作时,python会将字符串转换为正则表达式对象。而使用compile完成一次转换之后,在每次使用模式的时候就不用重复转换。当然,使用re.compile()函数进行转换后,re.search(pattern, string)的调用方式就转换为 pattern.search(string)的调用方式。

语法格式为:

re.compile(pattern[, flags])

参数:

  • pattern : 一个字符串形式的正则表达式

  • flags : 可选,表示匹配模式,比如忽略大小写,多行模式等,具体参数为:

    1. re.I 忽略大小写
    2. re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境
    3. re.M 多行模式
    4. re.S 即为 . 并且包括换行符在内的任意字符(. 不包括换行符)
    5. re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库
    6. re.X 为了增加可读性,忽略空格和 # 后面的注释

 栗子

import re
pattern = re.compile(r'\d+')                    # 用于匹配至少一个数字
m = pattern.match('one12twothree34four')        # 查找头部,没有匹配
print(m)#none
m = pattern.match('one12twothree34four', 2, 10) # 从'e'的位置开始匹配,没有匹配
print(m)
m = pattern.match('one12twothree34four', 3, 10) # 从'1'的位置开始匹配,正好匹配
print (m )                                        # 返回一个 Match 对象

print(m.group(0) )  # 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group() 或 group(0);

print(m.start(0) )  # 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;
print(m.end(0) ) #  方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0; print(m.span(0)) # 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group() 或 group(0); 返回结果 None None <_sre.SRE_Match object; span=(3, 5), match='12'> 12 3 5 (3, 5)

 

findall返回一个列表

在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。

注意: match 和 search 是匹配一次 findall 匹配所有。

语法格式为:

findall(string[, pos[, endpos]])

参数:

  • string : 待匹配的字符串。
  • pos : 可选参数,指定字符串的起始位置,默认为 0。
  • endpos : 可选参数,指定字符串的结束位置,默认为字符串的长度。

栗子

import re
pattern = re.compile(r'\d+')   # 查找数字
result1 = pattern.findall('runoob 123 google 456')
result2 = pattern.findall('run88oob123google456', 0, 11)#从0位开始到11位结束
 
print(result1)
print(result2)

输出结果:

['123', '456']
['88', '123']

re.finditer返回迭代器

和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。

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

栗子
import re
 
it = re.finditer(r"\d+","12a32bc43jf3") 
for match in it: 
    print (match.group() )

输出结果:

12 
32 
43 
3

 

re.split返回列表

split 方法按照能够匹配的子串将字符串分割后返回列表,它的使用形式如下:

re.split(pattern, string[, maxsplit=0, flags=0])

参数:

参数描述
pattern 匹配的正则表达式
string 要匹配的字符串。
maxsplit 分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志
栗子
print(re.split('\W', 'runoob,runoob,runoob')) # \w 匹配字母数字a-zA-Z0-9_及下划线,+代表多次
print(re.split('d', 'fiednaaldjdlaifeldghf'))#按字母d进行切片

返回结果

['runoob', 'runoob', 'runoob']
['fie', 'naal', 'j', 'laifel', 'ghf']

  

本篇参考菜鸟教程