python -- 内置模块re

时间:2022-05-20 03:46:55
一、正则表达式
 
正则表达式由普通字符和元字符组成,普通字符包含大小写字母,数字。在匹配普通字符的时候直接些就可以了。
元字符:元字符才是正则表达式的灵魂。
    1、字符组
        用方括号[]中括起来,在[]中出现的内容会被匹配
        如果字符组中的内容过多还可以使用-,[a-z][0-9][A-Z][A-Za-z0-9]
     2、简单元字符
         基本的元字符
.        匹配除换行符以外的任意字符
\w       匹配字母或数字或下划线
\s       匹配任意的空白符
\d       匹配数字
\n       匹配一个换行符
\t       匹配一个制表符
\b       匹配一个单词的结尾
^        匹配字符串的开始
$        匹配字符串的结尾
\W       匹配非字母和数字或下划线
\D       匹配非数字
\S       匹配非空白符
a|b      匹配字符a或字符b
()        匹配括号内的表达式,也表示一个组
[...]       匹配字符组中的字符
[^...]      匹配出了字符组中字符的所有字符

  

 
        3、量词
            匹配多个字符
 
*        重复0次或更多次
+        重复一次或更多次
{n}      重复n次
{n,}     重复n次或更多次
{m,n}    重复n到m次

  

     4、惰性匹配和贪婪匹配
            在量词中的* ,+,{}都属于贪婪匹配,就是尽可能多的匹配到结果
str:周游昨天去大连玩耍了
reg:周游.*
此时匹配的是整句话

     在使用  .*  后面如果加了?则是尽可能的少匹配,表示惰性匹配

str:周游昨天去大连玩耍了
reg:周游.*?
此时匹配的是 :周游

           .*?x 的特殊含义找到下一个x为止

str:abcdefghixjklmnopq
reg:  .*?x
结果:abcdefghi
5、分组
 
        在正则中使用()进行分组,比如匹配一个身份证号,老的身份证号由15位,新的有18位,而且有可能以X结尾
身份证号
^([1-9]\d{16}[0-9x]|[1-9]\d{14})$

邮箱
\w+@[0-9a-zA-Z]+\.[a-zA-Z]+
手机号
0?(13|14|15|17|18|19|16)[0-9]{9}
匹配生日
\d{4}(\-|\/|.)(([0][1-9])|([1][0-2]))\1(([0][1-9])|([1-2][0-9])|([3][0-1]))

  

 
6、转义
 
        在正则表达式中,有很多有特殊意义的是元字符,比如\n和\s等,如果要在正则中匹配正常的"\n"而不是“换行符”就需要对“\”进行转义,变成“\\”,在python中,无论是正则表达式,还是待匹配的内容,都是以字符的形式出现的,在字符串中\也有特殊的含义,本身还需要转义。所以如果匹配一次“\n”,字符串中要写成“\\n”,那么正则里就要写成“\\\\n”,这样比较麻烦,这时就需要用r'\n'这个该奶奶,此时的正则就是r'\\n'.
 
二、re模块
 
    re模块是python提供的一套关于处理正则表达式的模块,核心功能
    (?P<name>正则)
 
      1、search会进行匹配,但是如果匹配到了第一个结果,就会返回结果;如果匹配不上search则返回None
# search 搜索,查找
# 一旦匹配到结果,直接返回,如果匹配不到结果,返回None。
import re
result = re.search('\d','你的电话是什么182999999')
print(result)
print(result.group())


结果:
<_sre.SRE_Match object; span=(7, 8), match='1'>
1

   2、match 只能从字符串的开头进行匹配

# 匹配,从头开始匹配,相当于你的正则前面加了一个^
result = re.match("\d+","1188我的电话是188897888")
print(result)
print(result.group())

结果:
<_sre.SRE_Match object; span=(0, 4), match='1188'>
1188
search和match的区别:search查找,找到结果就返回,match从头开始匹配
 
      3、findall 查找所有,返回list
result = re.findall('\d+','baby的电话是1234565')
print(result)

结果:
['1234565']
 
      4、finditer 和findall差不多,但是finditer返回的是迭代器
 
result = re.finditer('\d+','周周的电话时1435634')
for el in result:
    print(el.group())

结果:
1435634
 
         5、group("name")  获取数据
 
# 坑:爬虫的坑
# .*?
result = re.finditer(r"姓名:(?P<name>.*?),爱好:(?P<hobby>.*?),","姓名:周周,爱好:跳舞,")
for el in result:
    print(el.group("name"),el.group("hobby"))
 6、compile()  编译
 
code = 'for i in range(10):print(i)'
c = compile(code,"","exec") # 编译
exec(c)  # 快速执行
reg = re.compile(r"\d+")  # 编译了一段正则,加载了一段正则
lst = reg.findall('明天,你要去12306吗,还是去10086')
print(lst)

结果:
['12306', '10086']
     7、 re.S  去掉  .  的换行
在网也源码中会有空白,加re.S可去掉这些空白
 
 
 
      8、split  切割
 
# 正则的常用操作
s = re.split("\d+","今天是29号,回头2号了就上课了")
print(s)

结果:
['今天是', '号,回头', '号了就上课了']

   9、sub 替换目标字符串

# 用正则替代
s = re.sub("\d+","__ps__","今天是29号,回头2号了就上课了")
print(s)

结果:
今天是__ps__号,回头__ps__号了就上课了
 
      10、subs 替换目标字符串并返回元组,并对替换的次数计数
 
s = re.subn("\d+","__ps__","今天是29号,回头2号了就上课了")
print(s)

结果:
('今天是__ps__号,回头__ps__号了就上课了', 2)

 11、(?:) 把表达式从python中的正则分组变成了原来正则表达式中的分组

lst = re.findall(r"a(?:\d+)c", "a3456c")  # 把括号python中的分组变成了原来正则表达式中的分组
print(lst)

lst = re.findall(r"a(\d+)c", "a3456c")  
print(lst)


结果:
['a3456c']
['3456']