python常用模块之re模块

一、正则表达式

1、概念

正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法。或者说:正则就是用来描述一类事物的规则。(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。
在python中,其典型应用场景有:

  1. 数据验证
  2. 数据替换
  3. 文本扫描
  4. 文本提取
  5. 文本分割

2、常用正则表(元字符)

参考来源
在这里插入图片描述

3、代码示例

'''
re模块基础
Version:01
author:jasn
data:2020-02-21

常用匹配模式(元字符)
http://blog.csdn.net/yufenghyc/article/details/51078107
'''
import re
#
# ==========================================================================================================================================
# 效果演示
str1 = 'In 2020, I must learn Python! & @'

#  \w:匹配数字字母及下划线
print(re.findall('\w',str1))
# 结果:['I', 'n', '2', '0', '2', '0', 'I', 'm', 'u', 's', 't', 'l', 'e', 'a', 'r', 'n', 'P', 'y', 't', 'h', 'o', 'n']

#  \W:匹配非字母数字及下划线
print(re.findall('\W', str1))
#  结果 :[' ', ',', ' ', ' ', ' ', ' ', '!', ' ', '&', ' ', '@']

#  \s匹配任意空白符
print(re.findall('\s',str1))
#  结果:[' ', ' ', ' ', ' ', ' ', ' ', ' ']

# \S 匹配任意非空字符
print(re.findall('\S', str1))
#  结果:['I', 'n', '2', '0', '2', '0', ',', 'I', 'm', 'u', 's', 't', 'l', 'e', 'a', 'r', 'n', 'P', 'y', 't', 'h', 'o', 'n', '!', '&', '@']

# \d 匹配任意数字,等价于[0-9]
print(re.findall('\d', str1))
print(re.findall('[0-9]', str1))   # 结果相同
# 结果:['2', '0', '2', '0']

# 、\D 匹配任意非数字
print(re.findall('\D', str1))
# 结果 :['I', 'n', ' ', ',', ' ', 'I', ' ', 'm', 'u', 's', 't', ' ', 'l', 'e', 'a', 'r', 'n', ' ', 'P', 'y', 't', 'h', 'o', 'n', '!', ' ', '&', ' ', '@']

# A 匹配字符串的开始 ;\Z匹配字符串的结束,有返回匹配的值,无返回空
print(re.findall('\AIn', str1))  # ['In'],\A==>^
print(re.findall('@\Z', str1))  # ['@'],\Z==>$

# ^ 匹配字符串的开头;$匹配字符串的结束
print(re.findall('^I', str1))   # ['I']
print(re.findall('@$', str1))   # ['@']

# ===========================================================================================================================================
# 重复匹配:| . | * | ? | .* | .*? | + | {n,m} |
# ===========================================================================================================================================
# . 匹配任意字符,除换行符外
print(re.findall('a.b','a1b'))  # ['a1b']
print(re.findall('a.b','a1b a*b a b aaab'))  # ['a1b', 'a*b', 'a b', 'aab']
print(re.findall('a.b','a\nb'))  # []
print(re.findall('a.b','a\nb', re.S))  # ['a\nb']

# 如果不使用re.S参数,则只在每一行内进行匹配,如果一行没有,就换下一行重新开始。
# 而使用re.S参数以后,正则表达式会将这个字符串作为一个整体,在整体中进行匹配。

print(re.findall('a.b','a\nb',re.DOTALL))  # ['a\nb']同上一条意思一样
# re.DOTALL。这使得正则表达式中的句点(.)可以匹配所有的字符,也包括换行符

#  * 匹配*左侧字符 一个或者 多个
print(re.findall('ab*','bbbbbbb'))  # []
print(re.findall('ab*','a'))  # ['a']
print(re.findall('ab*','abbbb'))  # ['abbbb']

# ? 匹配前面的子表达式 0 次或 1 次(等价于{0,1})
print(re.findall('ab?','a'))  # ['a']
print(re.findall('ab?','abbb'))  # ['ab']

# 匹配所有包含小数在内的数字
print(re.findall('\d+[.]?\d*',"asdfasdf123as1.13dfa12adsf1asdf3")) # ['123', '1.13', '12', '1', '3']


# .*  默认为贪婪匹配,一直匹配到结尾最后一个值
print(re.findall('a.*b','a1b22222222b'))  # 'a1b22222222b']

#  .*? (固定格式) 为非贪婪匹配:推荐使用,匹配到字符串第一个值
print(re.findall('a.*?b', 'a1b22222222b')) #['a1b']

# +  匹配前面的子表达式 1 次或多次(等价于{1, })
print(re.findall('ab','a'))  # []
print(re.findall('ab+','abbb'))  # ['abbb']

# {n,m}  m 和 n 均为非负整数,其中 n <= m,最少匹配 n 次且最多匹配 m 次
print(re.findall('ab{2}','abbb'))  # ['abb'] 匹配2个b
print(re.findall('ab{2,4}','abbb'))  # ['abb']
print(re.findall('ab{1,}','abbb'))  # 'ab{1,}' ===> 'ab+' 匹配1个到无穷个

print(re.findall('ab{0,}','abbb'))  # 'ab{0,}' ===> 'ab*' 匹配0个到无穷个


# ==============================================================================================================================================
# [] 用来表示一组字符,单独列出
print(re.findall('a[1*-]b', 'a1b a*b a-b'))  # []内的都为普通字符了,且如果-没有被转意的话,应该放到[]的开头或结尾
print(re.findall('a[^1*-]b', 'a1b a*b a-b a=b'))   # []内的^代表的意思是取反,所以结果为['a=b']
print(re.findall('a[0-9]b', 'a1b a*b a-b a=b'))  # []内的^代表的意思是取反,所以结果为['a=b']
print(re.findall('a[a-z]b', 'a1b a*b a-b a=b aeb'))  # []内的^代表的意思是取反,所以结果为['a=b']
print(re.findall('a[a-zA-Z]b', 'a1b a*b a-b a=b aeb aEb'))  # []内的^代表的意思是取反,所以结果为['a=b']

#\# print(re.findall('a\\c','a\c')) #对于正则来说a\\c确实可以匹配到a\c,但是在python解释器读取a\\c时,会发生转义,然后交给re去执行,所以抛出异常
print(re.findall(r'a\\c','a\c')) #r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义
print(re.findall('a\\\\c','a\c')) #同上面的意思一样,和上面的结果一样都是['a\\c']

# ===============================================================================================================================================

#():分组 匹配括号内表达式,也是一个分组
print(re.findall('ab+','ababab123'))  # ['ab', 'ab', 'ab']
print(re.findall('(ab)+123','ababab123'))  # ['ab'],匹配到末尾的ab123中的ab
print(re.findall('(?:ab)+123','ababab123'))  # findall的结果不是匹配的全部内容,而是组内的内容, ?: (固定写法)  可以让结果为匹配的全部内容
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"']

# |
print(re.findall('compan(?:y|ies)','Too many companies have gone bankrupt, and the next one is my company'))

二、re模块

1、re模块的使用

import re
str1 = 'In 2020, I must learn Python!'
pattern = re.compile('\d+')  //形式一:如果这种模式要反复重用,可以使用这种方法,将模式编译存在一个变量pattern中,便于重用
pattern.findall(str1)
['2020']
str1 = 'In 2020, I must learn Python! & @'
re.findall('\d+',str1)//形式二:如果这种模式只需要临时使用,可以直接使用re下的方法:(模式,内容)
['2020']

1.1、findall(pattern,string,flags = 0 )用法

以string列表形式返回string中pattern的所有非重叠匹配项。从左到右扫描该字符串,并以找到的顺序返回匹配项。如果该模式中存在一个或多个组,则返回一个组列表;否则,返回一个列表。如果模式包含多个组,则这将是一个元组列表。空匹配项包含在结果中。

str1 = 'In 2020, I must learn Python! & @'

#  \w:匹配数字[0-9]
print(re.findall('\d',str1))
#结果:['2', '0', '2', '0']

1.2、re.match(pattern,string,flags = 0 )用法
默认从以第一位开始搜索,且不是直接返回对象,返回一些附加信息
同search,不过在字符串开始处进行匹配,完全可以用search+^代替match
import re
str1 = 'In 2020, I must learn Python! & @'

print(re.match('a', str1))   # None
print(re.match('In', str1))  # <re.Match object; span=(0, 2), match='In'>

1.3、re.search(pattern,string,flags = 0 )用法
和match一样,但是可以从任意位置开始搜索,而不只是开头或设置位置
import re
str1 = 'In 2020, I must learn Python! & @'

print(re.search('In', str1))
print(re.search('e',str1).group())  # e,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None
'''
结果:
<re.Match object; span=(0, 2), match='In'>
e
'''

1.4、re.finditer(pattern, string, flags=0)用法
re.finditer()返回的是一个迭代器,需要对其进行遍历,才能获取数据。
import re

str1 = 'In 2020, I must learn Python! & @'
s = re.finditer('\d',str1)
for i in s:
    print(i,i.group(),end='\n')
'''
<re.Match object; span=(3, 4), match='2'> 2
<re.Match object; span=(4, 5), match='0'> 0
<re.Match object; span=(5, 6), match='2'> 2
<re.Match object; span=(6, 7), match='0'> 0
'''
1.5、re.sub(pattern,repl,string,count = 0,flags = 0 )的用法

返回通过用替换repl替换字符串中最左边的不重叠模式所获得的字符串。如果找不到该模式, 则返回的字符串不变。
repl可以是字符串或函数;如果是字符串,则处理其中的任何反斜杠转义。即,将其转换为单个换行符,将其转换为回车,依此类推。count参数表示将匹配到的内容进行替换的次数。

import re
str1 = 'In 2020, I must learn Python! & @'

print(re.sub('C语言','java',str1))
print(re.sub('Python','java',str1))

'''
In 2020, I must learn Python! & @
In 2020, I must learn java! & @
'''
print(re.sub('0','1',str1,)) #默认将所有的0,替换为1
print(re.sub('0','1',str1,1)) # 长度可选 1
'''
print(re.sub('0','1',str1,)) #默认将所有的0,替换为1
print(re.sub('0','1',str1,1)) # 长度可选 1
'''
1.6、re.split(pattern,string,maxsplit = 0,flags = 0 )的用法

通过出现模式来拆分字符串。如果在pattern中使用了捕获括号,那么模式中所有组的文本也将作为结果列表的一部分返回。如果maxsplit不为零,则最多会发生maxsplit分割,并将字符串的其余部分作为列表的最后一个元素返回。

import re
str1 = 'In 2020, I must learn Python! & @'
print(re.split('n',str1)) # 默认以所有n的位置来分割
print(re.split('n',str1,2)) # 以字符串从左到右顺序分割前两个n
print(re.split('(n)',str1,))  # 若将分隔符加入group,那么返回结果中也包括分隔符

'''
['I', ' 2020, I must lear', ' Pytho', '! & @']
['I', ' 2020, I must lear', ' Python! & @']
['I', 'n', ' 2020, I must lear', 'n', ' Pytho', 'n', '! & @']
'''
1.7、re.escape(pattern)方法

re.escape(pattern) 可以对文本(字符串)中所有可能被解释为正则运算符的字符进行转义的应用函数。

# re.escape(pattern) 可以对文本(字符串)中所有可能被解释为正则运算符的字符进行转义的应用函数。
import re
blog_url='https://blog.csdn.net/weixin_42444693'
print(re.escape(blog_url))

'''
https://blog\.csdn\.net/weixin_42444693
'''
1.8、re.compile(pattern,flags = 0)方法

将正则表达式模式编译为正则表达式对象,可使用match(),search()以及上述所述的其他方法将其用于匹配


prog = re.compile('\d{1}')  # 正则对象
print(prog.search('12abc').group())  # 通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
# 1

print(prog.match('123abc')) # <re.Match object; span=(0, 1), match='1'>
print(prog.match('123abc').group()) # 1

2、re模块的属性

2.1 re.A(re.ASCII)
让\w,\W,\b,\B,\d,\D,\s和\S 执行ASCII-只匹配完整的Unicode匹配代替。这仅对Unicode模式有意义,而对于字节模式则忽略。
2.2、re.I(re.IGNORECASE)
执行不区分大小写的匹配;类似的表达式也[A-Z]将匹配小写字母。
2.3、re.L(re.LOCALE)
让\w,\W,\b,\B和区分大小写的匹配取决于当前的语言环境。该标志只能与字节模式一起使用。不建议使用此标志,因为语言环境机制非常不可靠,它一次只能处理一种“区域性”,并且仅适用于8位语言环境。默认情况下,Python 3中已为Unicode(str)模式启用了Unicode匹配,并且能够处理不同的语言环境/语言。
2.4、re.M(re.MULTILINE)
指定时,模式字符'^'在字符串的开头和每行的开头(紧随每个换行符之后)匹配;模式字符'$'在字符串的末尾和每行的末尾(紧接在每个换行符之前)匹配。默认情况下,'^' 仅在字符串的开头,字符串'$'的末尾和字符串末尾的换行符(如果有)之前立即匹配。
2.5、re.S(re.DOTALL)
使 '.' 特殊字符与任何字符都匹配,包括换行符;没有此标志,'.' 将匹配除换行符以外的任何内容。
发布了46 篇原创文章 · 获赞 37 · 访问量 4524

猜你喜欢

转载自blog.csdn.net/weixin_42444693/article/details/104429058