正则

正则表达式及re模块

  正则表达式常用的方法

表达式含义
re.match() 从字符串的起始位置匹配,如果字符串第一个不满足规则,则返回None
re.search() 从整个字符串去匹配,找到一个就即刻返回结果,结束匹配,没有则返回None
re.findall() 从整个字符串去匹配,并返回所有的结果,以列表的形式展示,没有则返回[]
re.finditer() 从整个字符串去匹配,并返回所有的结果,以迭代器的形式展示

 

  常用的一般字符

  

一般字符说明例如
. 任意一个字符(除换行符‘\n’) >>> re.match(r'.','abc').group() 'a'
[] 把需要匹配的范围 [abc] <==>[a-c] >>> re.match(r'a[a-c]b','abbwe').group() 'abb'

  常用的预定义字符

  

预定义字符说明对等字符类
\d 任意一个数字 [0-9]
\D 任意一个非数字 [^0-9]
\s 任意一个空白符 [\t\n\x0B\f\r]
\S 任意一个非空白符 [^\t\n\x0B\f\r]
\w 任意一个字母或数字 [a-zA-Z0-9]
\W 任意一个非字母或数字 [^a-zA-Z0-9]

  数量词,用在 一般字符/预定义字符/(...)之后

数量词说明实例
* 匹配0个或多个,0到正无穷 >>> re.search(r'a*','weadwerqwe').group() '' (默认是非贪婪,匹配0个)
+ 匹配1个或多个,1到正无穷 >>> re.search(r'a+','weadwerqwe').group() 'a'(匹配一个,默认非贪婪)
匹配0个或1个 >>> re.search(r'a?','weadwerqwe').group() '' (匹配一个,默认非贪婪)
{m} 匹配m个相同的字符 >>> re.match(r'a{2}','aaaa').group() 'aa'
{m,n} 匹配m-n个相同的字符,若省略m,那么匹配0-n个相同的字符,若n省略,那么匹配m-无限个相同的字符 >>> re.match(r'a{2,4}','aaaa').group() 'aaaa' (匹配多的,默认贪婪模式)

  边界匹配

  

边界符号说明例子
^ 匹配字符串开头,在多行中匹配每一行的开头 >>> re.findall(r'^a','aweasdfqaawe') ['a']
$ 匹配字符串末尾,在多行中匹配每一行的末尾 >>> re.findall(r'a$','qeweea') ['a']
\A 仅匹配字符串开头 >>> re.findall(r'\Aa','abcwe\n,awer') ['a']
\Z 仅匹配字符串末尾 >>> re.findall(r'qe\Z','qweqwqe') ['qe']

 

  逻辑、分组

  

名称说明例子
逻辑或 | 左右两边满足一个即可 re.findall(r'a|b','ayebwiqa')
分组 (...) 被括起来的将作为分组 >>> re.search(r'(abc)','abcabcwu').group() 'abc'

  (.*) 贪婪匹配,会尽可能多的往后匹配

  (.*?) 非贪婪匹配,会尽可能少的匹配,是否加?影响匹配结果的长度,常用该匹配规则

import re
>>> re.search(r'a.*','sweaaeaaa').group()
'aaeaaa'
>>> re.search(r'a.*?','sweaaeaaa').group()
'a'

  总结一下常用的方法的使用

# match 从字符串第一个字符开始匹配,如果要准确匹配可以在末尾加上 $
>>> re.match(r'abc$', 'abc').group() # 准确匹配
'abc'
>>> re.match(r'a', 'Abc', re.I).group() # 忽略大小写匹配
'A'
>>> re.findall(r'a', 'AnsdkAkaa', re.I) # 忽略大小写匹配
['A', 'A', 'a', 'a']
>>> re.search(r'(?i)(abc){2}','ABCabc').group() # 忽略大小写匹配
'ABCabc'


# search
>>> re.search('tion','function').span() # 返回索引范围,匹配不到会报错
(4, 8)
>>> re.search('tion','function').group()  # 返回匹配到的值,匹配不到会报错
'tion'

# findall 有3种形式
>>> re.findall(r'a', 'aiuweaiueuiaiuqieuaqiua')
['a', 'a', 'a', 'a', 'a']

# split
>>> re.split('[ab]', 'abcd') # 按a或者b分割
['', '', 'cd']

# sub
>>> re.sub(r'\d', 'H', 'eva3egon4yuan4', 1) # 替换:把数字替换成H返回一个字符串,且之替换一个,默认替换
'evaHegon4yuan4'                                  #全部

# subn 
>>> re.subn('\d', 'H', 'eva3egon4yuan4') # 替换:把数字替换成H返回一个元祖,元祖由替换结果和替换次数组
('evaHegonHyuanH', 3)                           #

# compile
>>> re.compile('\d{3}')
re.compile('\\d{3}')
>>> rt = re.compile('\d{3}')  # 将正则表达式转换为正则表达式对象,然后再传给对应的方法来处理
>>> rt.search('qwei234i891').group()
'234'

#finditer  
>>> re.finditer('\d', 'ds3sy4784a')
<callable_iterator object at 0x000002265DD83C50> # 返回一个迭代对象

  注意

import re

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

ret = re.findall('www.(?:baidu|jd).com', 'www.jd.com')
print(ret)  # ['www.jd.com']


ret=re.split("\d+","eva3egon4yuan")
print(ret) #结果 : ['eva', 'egon', 'yuan']

ret=re.split("(\d+)","eva3egon4yuan")
print(ret) #结果 : ['eva', '3', 'egon', '4', 'yuan']

#在匹配部分加上()之后所切出的结果是不同的,
#没有()的没有保留所匹配的项,但是有()的却能够保留了匹配的项,
#这个在某些需要保留匹配部分的使用过程是非常重要的。

  例子

案例1
s ="1113446777"  
把s分为1111, 3, 44, 6, 777

# 方法1
list_s =list(s)

for i in range(1,len(s)):
    if s[i] != s[i-1]:
        list_s[i] = ','+ s[i]

s2 = ''.join(list_s)
print(s2)

#方法二

list_s2 = []
ret = re.finditer(r'(\d)\1*', s)
val = next(ret).group()
while val:
    list_s2.append(val)
    try:
        val = next(ret).group()
    except:
        val = ''
print(list_s2)

案例2
>>> s = '1111werwrw3333rertert4444'
>>> p = r'(\d)\1+([a-zA-Z]*)' # 注意findall前面提到的3种方式,字符串,(),嵌套(),这是最后一种表现形式
>>> import re
>>> re.findall(p,s)
[('1', 'werwrw'), ('3', 'rertert'), ('4', '')]

>>> m = re.search(p,s)  
>>> m.group()  
'1111werwrw'  
>>> m.group(1)  
'1'  
>>> m.group(2)  
'werwrw'  
>>> m.groups()  
('1', 'werwrw')  
>>> m = re.finditer(p,s)   # 通过迭代器来处理
>>> m.next().group()  
'1111werwrw'  
>>> m.next().group()  
'3333rertert'  
>>> m.next().group()  
'4444'  
>>> m.next().group()  
Traceback (most recent call last):  
  File "<stdin>", line 1, in <module>  
StopIteration  

综上:
group():母串中与正则表达式匹配的子串;
group(0):结果与group()一样;
groups():所有group组成的一个元组,group(1)是与正则表达式中第一个group匹配成功的子串,group(2)是第二个,依次类推,如果index超了边界,抛出IndexError;
findall():返回的就是所有groups的数组,就是group组成的元组的数组,母串中的这一撮组成一个元组,那一措组成一个元组,这些元组共同构成一个list,就是findall()的返回结果。另,如果groups是只有一个元素的元组,findall的返回结果是子串的list,而不是元组的list了。

  

>>> re.findall("([a-z])+", "thAis")
['h', 's']

 

posted @ 2020-03-18 10:08  海澜时见鲸  阅读(166)  评论(0)    收藏  举报