python之正则re模块

 1.正则的语法:

 中文教程:https://wizardforcel.gitbooks.io/py-re-guide/content/index.html

 1.re的数量词:

1. ^   匹配度字符串开始位置

2. $   匹配字符串结束的地方:

tr = 'jgko22rkdljgkd'
r2 = re.findall('^jgkd', tr)
print(r2)   # []是空的
r4 = re.findall('^jgko', tr)
print(r4)  # ['jgko']

r3 = re.findall('^rk', tr)
print(r3)  # []
print(re.findall('^gk', tr))  # []

# 说明是^只在字符串第一位进行匹配,第一位没有匹配上的话,就停止匹配返回空值!

r5 = re.findall('gkd$', tr)
print(r5)  # ['gkd']
r6 = re.findall('gk$', tr)
print(r6)  # []
print(re.findall('rkd$', tr))  # [],没有匹配成功!

# 同理$是指匹配字符串最后一位字符,存在且符合匹配则成功,不然就返回空值!  

花了十几分钟自己试了一遍,同时也是复习了,之前学的时候懂了,由于当时自己的笔记做的不好,甚至是没有记下来,搞得现在想复习都没有地方看,总结的才是自己的!好好的写博客吧!

5. x? 匹配1个或者0个x这个字符(说明x表示任意一个前面的字符,下同)

6. x*  匹配0个或者是无数个x

7.x+  匹配1个或者无数个x

tr = 'xpathhhhpa6663324'
r2 = re.findall('pat*', tr)
print(r2)  # ['pat', 'pa']

r3 = re.findall('path+', tr)
print(r3)  # ['pathhhh']

print(re.findall('pat?', tr))  # ['pat', 'pa']

8.x{n, m}  匹配n到m个x, 前闭后闭

r = re.findall('z2{1,4}', 'z2222yy')
print(r)  # ['z2222']

x{m} 表示可以匹配m个x字符

9.   .   匹配任意的字符

tr = 'zhangtt'
z = re.findall('z...g', tr)
print(z)   # ['zhang']

 2.re的预定义字符串:

1. /d  匹配数字:等于[1 -9]

2./D   匹配非数字:等于[^/d]

tr = 'zh285j34if12'
z = re.findall('zh\d{3}', tr)
print(z)   # ['zh285']
print(re.findall('4\D{2}1', tr))   # ['4if1']

3./s   匹配空字符串

4./S  匹配非空字符串

tr = 'z h285j34if12'
z = re.findall('z\sh', tr)
print(z)   # ['z h']
print(re.findall('h\S8', tr))   # ['h28']

5.\w  匹配单词字符:等于[a-zA-Z0-9]

6.\W  匹配非单词字符: 等于[^\w]

 3.正则分组:       ******

 》1.正则表达式中用()括起来的表达式为一个分组,

tr = 'jgko22rko68jgkd'
pattern = re.compile('(ko\d{2})')
r = pattern.search(tr)
print(r.group())   # ko22   

小组是从左向右计数的,从1开始。组可以被嵌套。计数的数值可以通过从左到右计算打开的括号数来确定。

p = re.compile('(a(b)c)d')
m = p.match('abcd')
m.group(0)  # 'abcd'   拿到的是一个整体匹配结果
m.group(1)  # 'abc'  第一个组的结果
m.group(2)  # 'b' 第二个组的结果

group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。

 m.group(2,1,2)
('b', 'abc', 'b')

The groups() 方法返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。

m.groups()
('abc', 'b')

》2.也同样可以命名分组 (?P<name>...),捕获的时候接受组的名字,也同样接受组的组号

tr = 'jgko22rko68jgkd'
pattern = re.compile('(?P<koy>ko\d{2})')
r = pattern.search(tr)
print(r.group('koy'))  # ko22  这个是通过组的名字得到的
print(r.group(1))   # ko22   这个是组号得到的信息
print(r.group(0))   # ko22  但是这个group(0)代指的是整个group,这里面就匹配到了一个,所以就一样的了!  

  

 2.re搜索函数:

 1.re.search():   ****

  re.search(pattern, string, flags)

第一个参数是正则表达式,如果匹配成功,则返回一个Match,否则返回一个None; 
第二个参数表示要匹配的字符串; 
第三个参数是标致位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

特点: 扫描整字符串,然后返回第一个成功匹配的结果

str = 'djangostudyjand'
r = re.search('jan\w', str)
print(r)  # <_sre.SRE_Match object; span=(1, 5), match='jang'>
print(r.group())  # jang
# 用group来打印一下匹配到的数据

匹配到了两个,但就只返回一个第一个匹配成功的数据!

 2.re.match():  ***

 re.match(pattern, string, flags)

第一个参数是正则表达式,如果匹配成功,则返回一个Match,否则返回一个None; 
第二个参数表示要匹配的字符串; 
第三个参数是标致位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

特点:re.match()是只匹配字符串的第一位,如果不符合的话,则匹配失败返回none

str = 'djangostudy'
r = re.match('jan\w', str)
print(r)  # none

r2 = re.match('djan\w', str)
print(r2)  # <_sre.SRE_Match object; span=(0, 5), match='djang'>
print(r2.group())  # djang
# 用group来打印一下匹配到的数据

 》2.这里面加上起始位置的话,就以起始的位置作为匹配的地方!,仅仅是在re.compile()的正则表达式下才可以用!详情见下方的re.compil()用法!

import re

pattern = re.compile('\d+')
m = pattern.match('abc123zha', 3, 5)
print(m.group())
# 12

# match的用法,可以在后面加上匹配起始位置以及结束位置!
#  def match(self, string: AnyStr, pos: int = ...,
#               endpos: int = ...) -> Optional[Match[AnyStr]]: ...

 3.re.compile()    ***

 re.compile(pattern[, flags])

compil函数就是一个预生成的正则表达式对象(pattern),配合match()和search()函数使用

  • 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 为了增加可读性,忽略空格和 # 后面的注释
str = 'djangozh686'
pattern = re.compile('zh\d{2}')  # 匹配两个数字
r = pattern.search(str)
print(r)  # <_sre.SRE_Match object; span=(6, 10), match='zh68'>这是一个match对象
print(r.group(0))  # zh68 可以省略0
print(r.start(0))  # 6  可以省略0
print(r.end(0))  # 10
print(r.span(0))  # (6, 10)

其中匹配返回的match对象中:

  • group([group1, …]) 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可直接使用 group() 或 group(0)
  • start([group]) 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索引),参数默认值为 0;
  • end([group]) 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引+1),参数默认值为 0;
  • span([group]) 方法返回 (start(group), end(group))
pattern = re.compile('([a-z]+) ([a-z]+)', re.I)  # re.I表示忽略字母的大小写!
z = pattern.match('Hello World My Choice')
print(z)  # <_sre.SRE_Match object; span=(0, 11), match='Hello World'>
print(z.group(0))  # Hello World
print(z.span(0))  # (0, 11)
print(z.group(1))  # Hello
print(z.group(2))  # World
print(z.span(1))   # (0, 5)
print(z.span(2))   # (6, 11)
# python 的模块是真的很强!  

》》2.在compile的pattern的对象里有一种特殊的用法:

其中 pattern.match(), pattern.findall(), pattern.search(), pattern.findlter()都可以在其括号加上起始字符位置和结束位置,用来精确匹配!                  ********

import re

pattern = re.compile('\d+')
m = pattern.match('abc123zha', 3, 5)
print(m.span())
# (3, 5)
print(m.group())
# 12

p = re.search('\d+', 'abc123zha789', 2, 6)  
print(p)
# 出错!re的模块没有这个用法
    def search(self, string: AnyStr, pos: int = ...,
               endpos: int = ...) -> Optional[Match[AnyStr]]: ...
    def match(self, string: AnyStr, pos: int = ...,
              endpos: int = ...) -> Optional[Match[AnyStr]]: ...
    # New in Python 3.4
    def fullmatch(self, string: AnyStr, pos: int = ...,
                  endpos: int = ...) -> Optional[Match[AnyStr]]: ...
    def split(self, string: AnyStr, maxsplit: int = ...) -> list[AnyStr]: ...
    def findall(self, string: AnyStr, pos: int = ...,
                endpos: int = ...) -> list[Any]: ...
    def finditer(self, string: AnyStr, pos: int = ...,
                 endpos: int = ...) -> Iterator[Match[AnyStr]]: ...

 4.re.findall()      *****

这个是最重要的搜索匹配函数!也是最常用的

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

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

 返回所有匹配到的数据,默认返回一个列表!

tr = 'mypython123pytton'
py = re.findall('py\D{1,2}on', tr)
print(py)  # ['python', 'pytton']
print(py[1])  # pytton

 5.re.finditer()  ***

 和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并把它们作为一个迭代器返回。这个就比较好用了,在某些场景下!

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

  • pattern    匹配的正则表达式
  • string     要匹配的字符串
  • flags      标志位详细用法见下方
import re
 
it = re.finditer(r"\d+","12a32bc43jf3") 
for match in it: 
    print (match.group() )

  6.re.split()    ****

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

  • pattern    匹配的正则表达式
  • string     要匹配的字符串
  • maxsplit      分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数。
  • flags      标志位详细用法见下方
tr = 'python, django,re.'
res = re.split('\W+', tr)
print(res)  # ['python', 'django', 're', '']  以非字母或者数字的地方进行切割
# 分割的话 会有空格 
re.split('\W+', ' runoob, runoob, runoob.', 1)  # 就分割一次
# ['', 'runoob, runoob, runoob.']

re.split('a*', 'hello world')   # 对于一个找不到匹配的字符串而言,split 不会对其作出分割
# ['hello world']

  7.pattern.span()  

  span()用于打印匹配到的字符串的位置 :

import re

pattern = re.compile('\d+')
m = pattern.match('abc123zha', 3, 5)
print(m.span())  
# (3, 5)
print(m.group())
# 12

# match的用法,可以在后面加上匹配起始位置以及结束位置!
#  def match(self, string: AnyStr, pos: int = ...,
#               endpos: int = ...) -> Optional[Match[AnyStr]]: ...

  8.re.sub()       ****

re.sub()用于替换字符串作用:

st = 'zh12pt3456youji'
pattern = re.compile('\d{2}')
m = pattern.sub('kl', st)
print(m)  # zhklptklklyouji

默认是替换所有匹配到的字符串!

 标志位:

正则表达式修饰符 - 可选标志

正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:

修饰符 描述
re.I 使匹配对大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配,影响 ^ 和 $
re.S 使 . 匹配包括换行在内的所有字符
re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。

猜你喜欢

转载自www.cnblogs.com/Pikachuzj/p/9484452.html