首页 > 其他 > 详细

25 -1 正则 re模块 (findall、search、match、sub、subn、split、compile、finditer)

时间:2020-04-06 22:08:33      阅读:118      评论:0      收藏:0      [点我收藏+]
帮助学习的工具 http://tool.chinaz.com/regex/  


字符组 []
在一个字符的位置上能出现的内容
[1bc]         是一个范围
[0-9][A-Z][a-z] 匹配三个字符
[abc0-9] 匹配一个字符
[0-9a-zA-Z] 匹配一个字符

技术分享图片
[1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9X]
18位身份证号

 

\d == [0-9]       也表示匹配一个字符,匹配的是一个数字
\w == [0-9a-zA-Z_]  也表示匹配一个数字字母下划线
\s == [\n \t]    包括回车 空格 和 制表符tab
\n           匹配回车
\t           匹配制表符 (tab)
\D           匹配非数字
\W           匹配非数字字母下滑线
\S           匹配非空白
技术分享图片
[\d\D] [\w\W] [\s\S]
匹配所有
正则表达式的语法

作用 : 一种匹配字符串的规则
应用 : 登录注册的表单验证
爬虫 自动化开发 日志分析


1. 元字符
字符组 [] [^] | ()
|的用法   [1-9]\d{16}[0-9X]|[1-9]\d{14} 身份证号
()的用法   [1-9]\d{14}(\d{2}[1-9X])?   身份证号
  \d+(\.\d+)?          小数或者整数
\w \d \s(\n,\t, ) \W \D \S
^ $
.       匹配除了换行符之外的所有字符 爬虫容易用,表单不容易用

    
   2. 量词
    ? 0-1
      + 1-无穷
       * 0-无穷
     {n},{n,},{n,m}
    3.特殊的用法和现象
    ?的使用
  1. 在量词的后面跟了一个 ? 取消贪婪匹配 非贪婪(惰性)模式
    ?? \ *? \+? \ {n}?
  李.{1,3}?和 李莲英和 惰性匹配 回溯算法
  最常用 .*?x 匹配任意字符直到找到一个x
总结
元字符
元字符量词 默认贪婪匹配- 回溯算法 (先拿他个最大量,然后往回找匹配的)

元字符量词? 表示惰性匹配 - 惰性匹配 (一个个匹配,有了就停止匹配了)

1、匹配任意长度的正整数   [1-9]\d*
2、匹配小数       -?\d+\.\d+
3、匹配整数或者小数:
  -?\d+\.?\d*    有缺陷 1. 2.这样的内容都能被匹配上
  -?\d+\.?\d+ 有缺陷 1 2 这样的一位数都匹配不上了
  -?\d+(\.\d+)? 准确的
4、匹配负数    -0\.\d+|-[1-9]\d+(\.\d+)?
5、匹配qq号   [1-9]\d{4,11}
6、匹配长度为11位的电话号码 1[3-9]\d{9}
7、长度为8-10位的用户密码 : 包含数字字母下划线和?@
[\w@?]{8,10}
8、匹配验证码:4位数字字母组成的
[\da-zA-Z]{4}

9、从类似
<a>wahaha<\a>
<b>banana<\b>
<h1>qqxing<h1>
<script>salkdjgh<\script>
这样的字符串中,
1)匹配出wahaha,banana,qqxing内容。 >\w+<
2)匹配出a,b,h1这样的内容         <\w+>

10、1-2*((60-30+(-40/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))
从上面算式中匹配出最内层的小括号
(-40/5)(9-2*5/3+7/3*99/4*2998+10*568/14)(-4*3)(16-3*2)
\([\d\.+\-*/]+\)
\([^()]+\)

正则表达式中的转义 :
  
‘\(‘  表示匹配小括号

[()+*?/$.]   在字符组中一些特殊的字符会现出原形

[-]只有写在字符组的首位的时候表示普通的减号,写在其他位置的时候表示范围[1-9],如果就是想匹配减号 [1\-9]

 python中的转义符
  
‘\n‘  # \转义符 赋予这个n一个特殊的意义 表示一个换行符

print(‘\\n‘)     # 取消转义 \n

print(‘C:\\next‘)  # 取消转义 C:\next   等同于 print(r‘C:\next‘)
 
re模块 
  对字符串 进行匹配
  一 、findall (重要)
    
ret = re.findall(\d+,19874ashfk01248)

print(ret)      # 参数 返回值类型:列表 返回值个数:1 返回值内容:所有匹配上的项   [‘19874‘, ‘01248‘]

 

  二、search (重要)

匹配到

ret2 = re.search(\d+,@$19874ashfk01248)
print(ret2) #  返回值类型: 正则匹配结果的对象  返回值个数:1 如果匹配上了就返回对象
# <re.Match object; span=(2, 7), match=‘19874‘>
if ret2:print(ret2.group()) # 返回的对象通过group来获取匹配到的第一个结果 
# 19874
 

没匹配到

ret3 = re.search(\s+,19874ashfk01248)
print(ret3) #  返回值类型: None   如果没有匹配上就是None

 

三 、match (一般)

  

ret4 = re.match(\d+,19874ashfk01248)
print(ret4)     # <re.Match object; span=(0, 5), match=‘19874‘>
ret5 = re.match(\d+,%^19874ashfk01248)
print(ret5)   # None


print(ret4.group())   # 19874

四、替换 python

  1、自带替换 replace

  

print(replace789,24utdeedeeeeshf.replace(e,H,3))    # e替换成H ,替换3个
 # rHplacH789,24utdHedeeeeshf

 

  2、re 的sub  (一般)

ret = re.sub(\d+,H,replace789nbc2xcz392zx)   # 正则,替换内容,字符串
print(ret)       # replaceHnbcHxczHzx
ret = re.sub(\d+,H,replace789nbc2xcz392zx,48495,1)
print(ret)     #  replaceHnbc2xcz392zx,48495

  3、subn(一般)

ret = re.subn(\d+,H,replace789nbc2xcz392zx)  #正则,替换值,字符串
print(ret)    # 返回一个元组 (替换后的字符串,替换次数)
# (‘replaceHnbcHxczHzx‘, 3)

 

五、切割

split
1、python 内置函数
print(alex|83|.split(|))      # [‘alex‘, ‘83‘, ‘‘]

  2、re中的split

ret = re.split(\d+,alex83egon20taibai40) 
print(ret)    #[‘alex‘, ‘egon‘, ‘taibai‘, ‘‘]

 

六、进阶方法 - 爬虫\自动化开发

1、compile  (重要)-----节省时间

 一般都是直接带入正则表达式,直接匹配结果,当要重复使用改正则表达式,程序就要重新编译理解它,继而导致程序效率低
re.findall(-0\.\d+|-[1-9]+(\.\d+)?,alex83egon20taibai40)  #  --> python解释器能理解的代码 --> 执行代码

 

那,如何让程序更加高效呢? 我们可以使用预编译compile ,程序直接调用编译结果使用即可,不用重复编译了

    (节省时间 : 只有在多次使用某一个相同的正则表达式的时候,这个compile才会帮助我们提高程序的效率)

ret = re.compile(-0\.\d+|-[1-9]\d+(\.\d+)?)
res = ret.search(alex83egon-20taibai-40)


res2 = ret.search(...)
res3 = ret.search(...)
...
print(res.group())

2、finditer (重要)--节省空间
  
print(re.findall(\d,sjkhkdy982ufejwsh02yu93jfpwcmc))
ret = re.finditer(\d,sjkhkdy982ufejwsh02yu93jfpwcmc)     # 得到了一个迭代器(可迭代对象)
for r in ret:
    print(r.group())


--------------------------------
9
8
2
0
2
9
3

关于分组的坑


findall 关于分组的坑--- 分组的优先显示
                优先显示分组内的内容
import re
ret = re.findall(-0\.\d+|-[1-9]\d*(\.\d+)?,-1asdada-200)
print(ret)     # [‘‘, ‘‘]
ret = re.findall(www.baidu.com|www.oldboy.com,www.oldboy.com)
print(ret)      # [‘www.oldboy.com‘]


ret = re.findall(www.(baidu|oldboy).com,www.oldboy.com)
print(ret)      #   [‘oldboy‘]
ret = re.findall(www.(?:baidu|oldboy).com,www.oldboy.com)
print(ret)      # 取消分组优先(?:) [‘www.oldboy.com‘]

 

split 遇到分组 会保存被切掉的内容

ret = re.split(\d+,alex83egon20taibai40)
print(ret)
ret
= re.split((\d+),alex83egon20taibai40) print(ret) # 遇到分组,保存被切掉的内容 ---------------------------------------------------- [alex, egon, taibai, ‘‘] [alex, 83, egon, 20, taibai, 40, ‘‘]

search遇到分组
    通过group(n)就能拿到group中的匹配的内容
ret = re.search(\d+(.\d+)(.\d+)(.\d+)?,1.2.3.4-2*(60+(-40.35/5)-(-4*3)))
print(ret.group())
print(ret.group(1))
print(ret.group(2))
print(ret.group(3))

---------------------------
1.2.3.4
.2
.3
.4

 

小试牛刀

 

一、要求匹配到表达式"1-2*(60+(-40.35/5)-(-4*3))"中所有整数

1.拿到所有的数,(然后把小数去掉)

技术分享图片
import re

ret = re.findall(r"\d+(?:\.\d+)?", "1-2*(60+(-40.35/5)-(-4*3))")
print(ret)
View Code

2.直接匹配所有整数

分组思路,我不想要小数,但是无法避免,我就匹配小数,但是咱不显示你就行了

# 思路是 我们匹配小数|整数,但是小数取消优先显示,优先显示的是后面的整数,即得到结果
ret = re.findall(r"\d+(?:\.\d+)|(\d+)", "1-2*(60+(-40.35/5)-(-4*3))")
print(ret)   # [‘1‘, ‘2‘, ‘60‘, ‘‘, ‘5‘, ‘4‘, ‘3‘]
ret.remove(‘‘)  # [‘1‘, ‘2‘, ‘60‘, ‘5‘, ‘4‘, ‘3‘]
print(ret)

 

二、匹配html 标签内容

1、匹配<a>wahaha<\a>

  

import re
ret = re.findall(>(\w+)<,r<a>wahaha<\a>)
print(ret)    # [wahaha]

2、嘿,那假如想匹配两端标签不同的中间内容呢<a>wahaha</b>  (当然这是假设)

# 利用分组!
ret = re.search(r<(\w+)>(\w+)</(\w+)>, r<a>wahaha</b>)
print(ret.group())
print(ret.group(1))
print(ret.group(2))



--------------------------------
<a>wahaha</b>
a
wahaha

 

七、分组命名  

        (?P<name>正则表达式)

1、通过group(分组名),获取值
ret = re.search("<(?P<name>\w+)>\w+</(?P=name)>","<h1>hello</h1>")
print(ret.group(name))    # 结果 :h1
print(ret.group())          # 结果 :<h1>hello</h1>

 同样的通过group(n),当然也是可以的呀

ret = re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>")
print(ret.group(1))
# print(ret.group())  #结果 :<h1>hello</h1>

同样的 :

ret = re.search(r<(?P<tag>\w+)>(?P<c>\w+)</(\w+)>, r<a>wahaha</b>)
print(ret.group())          # <a>wahaha</b>
print(ret.group(tag))     # a
print(ret.group(c))       # wahaha

推荐一本正则的书 :《正则指引》        -------- 以python 为基础的书


小拓展

1.groups()是什么?
技术分享图片
import re
ret = re.search(r\d+(\.\d)(\d),r1.23+2.3+3-4*5)
print(ret.group())
print(ret.group(1))
print(ret.group(2))
print(ret.groups())

——————————————————————
1.23
.2
3
(.2, 3)     # 可知,groups() 获取分组内的内容,以str形式放入元组内
View Code

 

2.split 分组保留
import re
ret3 = re.split(\d(\w), ***1a***2b***3c**)
print(ret3)     #  [‘***‘, ‘a‘, ‘***‘, ‘b‘, ‘***‘, ‘c‘, ‘**‘]

# 以数字+数字字母下划线  的组合切开,但是保留后面的分组了

 





25 -1 正则 re模块 (findall、search、match、sub、subn、split、compile、finditer)

原文:https://www.cnblogs.com/zhuangdd/p/12644081.html

(1)
(1)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!