正则表达式

正则表达式的基础内容就不一一罗列了,都记录在了有道云笔记上

正则表达式重要点总结

1.断言

了解一个零宽的知识:占有字符和零宽度:
如果子表达式匹配到的是字符内容,而非位置,并被保存到最终的结果中,那么就认为这个字表达式是占有字符的;如果子表达式匹配的仅仅是位置,或者匹配的内容并不保存最终的匹配结果中,那么就认为这个表达式是零宽度的。

零宽断言举例
rained(?=exp)匹配右边右边一定紧挨着exp的rained
(?<=exp)rained匹配左边一定挨着exp的rained
负向零宽断言举例
rained(?!exp)匹配右边右边一定不紧挨着exp的rained
(?<!exp)rained匹配左边一定不紧挨着exp的rained

2.分组

分组解释
(exp)使用()指定一个字表达式,也叫分组,捕获后会自动分配组号从1开始,也可以改变优先级
(?:exp)不需要捕获分组,仅仅是为了改变优先级
(?P< name>exp)Python中的命名分组

3.引擎选项

模式说明Python使用方法
IgnoreCase匹配时忽略大小写re.I、re.IGNORECASE
Singleline单行模式,可以匹配所有字符,包括\nre.S、re.DOTALL
Multiline多行模式^行首、$行尾部re.M、re.MULTILINE
IgnorePatternWhitespace忽略表达式中的空白字符,如果要使用空白字符用转义,#可以用来注释re.X、re.VERBOSE

注解:
①默认模式下:不能匹配换行符,只是一行,只有一个开头和结尾
②单行模式下: .可以匹配换行符
③多行模式下: .不能匹配换行符,每行都有行首和行位

Python中re模块常用方法

python re模块官方文档点这里

1.re.compile(pattern,flags=0)

flags表示匹配的模式,可以通过位的OR操作来结合(|操作符)。

返回正则表达式对象regex,可以用于匹配,通过这个对象的方法match(),search()以及其他描述。

In [1]: import re

In [2]: s = "abc123"

In [3]: regex = re.compile("\d+")

In [4]: regex.search(s)
Out[4]: <re.Match object; span=(3, 6), match='123'>

In [5]: regex.search(s).group()
Out[5]: '123'

注解: 通过re.compile()编译后的样式,和模块级的函数会被缓存,所以少数的正则表达式使用无需考虑编译的问题。

2.单次匹配的方法==

1° re.match(pattern,string,flags=0)

只能在位置0匹配,无视多行模式的行首,位置0
单次匹配,匹配不到返回None
返回值为match对象

2° re.search(pattern,string,flag=0)

单次匹配,只返回第一个匹配到的,匹配不到返回None
找到就不往后面找了
返回值为match对象

3° re.fullmatch(pattern,string,flags=0)

全长匹配,应用于所有字符串,必须全部匹配上,否则返回None
返回值为match对象

3.全文匹配的方法

1° re.findall(pattern,string,flags=0),返回的东西!!!

全局匹配,返回所有满足pattern的string的一个列表

return a list
如果正则表达式带分组

  • 一个分组:返回组列表list of groups =>> [‘a’, ‘b’,]
    因为groups()是一个字符串的元组,所有返回为字符串的list

  • 多个分组:返回元组列表list of tuples => [(), (),]
    因为groups()是多个字符串的元组,所以返回元组列表

In [1]: import re

In [2]: s ="band\nbag\nbad\nabsolute"

In [3]: re.findall("b[a-z]+(d)",s) # 返回一个字符列表
Out[3]: ['d', 'd'] 

In [4]: re.findall("b(?P<A>a)\w*(?P<B>d)",s) # 返回一个元组列表
Out[4]: [('a', 'd'), ('a', 'd')]

In [5]: re.findall("b[a-z]+d",s) 
Out[5]: ['band', 'bad'] 

2° re.finditer(pattern,string,flags=0)
返回一个保存了match对象的iterador
从左到右依次匹配,匹配按熟悉怒排列。空匹配也包括在结果内。

In [1]: import re

In [2]: s = "a1b2c3d4"

In [3]: x = re.finditer("\d",s)

In [4]: for i in x:
   ...:     print(i)
   ...:     
<re.Match object; span=(1, 2), match='1'>
<re.Match object; span=(3, 4), match='2'>
<re.Match object; span=(5, 6), match='3'>
<re.Match object; span=(7, 8), match='4'>

3° 匹配替换
re.sub(pattern,repl,string,count,flags)

使用pattern对字符串string进行匹配,对匹配项使用repl替换

In [7]: re.sub("\d","☆",s)
Out[7]: 'a☆b☆c☆d☆'

In [8]: s = "a1b2c3d4"

In [9]: re.sub("\d","☆",s)
Out[9]: 'a☆b☆c☆d☆'

In [10]: s
Out[10]: 'a1b2c3d4'

re.subn(pattern, repl, string, count=0, flags=0)

行为和sub()相同,但是返回一个元组(字符串,替换次数)

In [10]: s
Out[10]: 'a1b2c3d4'

In [11]: re.subn("\d","☆",s)
Out[11]: ('a☆b☆c☆d☆', 4)

In [12]: s
Out[12]: 'a1b2c3d4'

注意上面两种匹配替换模式不对原字符串进行操作,返回值为替换过的副本。

4° 分隔字符串

re.split(pattern,string,maxsplit,flags)
返回值为一个列表。

下面举例易错点:

In [12]: s
Out[12]: 'a1b2c3d4'

In [13]: re.split("(\w)",s)
Out[13]: ['', 'a', '', '1', '', 'b', '', '2', '', 'c', '', '3', '', 'd', '', '4', '']

In [14]: re.split("\w",s)
Out[14]: ['', '', '', '', '', '', '', '', '']

In [15]: re.split("\d",s)
Out[15]: ['a', 'b', 'c', 'd', '']

In [16]: re.split("(\d)",s)
    ...: 
Out[16]: ['a', '1', 'b', '2', 'c', '3', 'd', '4', '']

注意:
①如果pattern中捕获到括号(也就是分组),那么所有的组里的文字也会包含在返回的列表中。
②如果分隔符里有捕获组合,并且匹配到字符串的开始,那么结果将会以一个空字符串开始。对于结尾也一样。

4.分组

使用小括号的pattern分组捕获的数据被放到了group中。

对于返回为match对象的方法,总结以下几点:

  • groups()和group()可以通过match对象获得
  • group()和group(0)相同,
  • group(n)如果n超界,会IndexError
  • groups()是所有group组成的元组,group(0)除外

对于命名分组(?Pexp)可以使用groupdict返回所有命名的分组
可以使用matchobj.group(name)获取对应分组捕获的值

In [21]: s = "abc123_ "

In [22]: re.search("([a-z]+)",s)
Out[22]: <re.Match object; span=(0, 3), match='abc'>

In [23]: x = re.search("([a-z]+)",s)

In [24]: x.groups() # 返回所有分组匹配结果组成的元组
Out[24]: ('abc',)

In [25]: x.group() == x.group(0) # 这两个值相同, 返回pattern匹配的结果
Out[25]: True

In [26]: x.group(0) 
Out[26]: 'abc'

In [27]: x.group(1) # 返回第一个分组匹配的结果
Out[27]: 'abc'

In [28]: x.group(2) # 分组索引超界,报错IndexError
Traceback (most recent call last):

  File "<ipython-input-28-43f0dc0c9eec>", line 1, in <module>
    x.group(2)

IndexError: no such group

经典正则表达式练习题

正则表达式结合python验证密码强度问题
题目要求:
判断密码强度(因为只包含\w内的不包括汉字的密码,也不健壮…)
实际环境:
大写字母,小写字母,数字,下划线等除了汉字和空白字符的字符
拿到一个pwd,反馈密码强度
三个强度:weak,middle,strong
规则:
1.只含有二种字符的就是weak
2.含有三种的字符的就是midum
3.含有四种的就是strong

import re
def jduge(pwd):
    # 下面来判断密码强度
    Number = re.compile("[0-9]")
    Lower_case = re.compile("[a-z]")
    Upper_case = re.compile("[A-Z]")
    others = re.compile("[^a-zA-Z0-9]") 
    type = 0 #  特征值
    # 判断是否是合法字符
    if len(pwd) < 8 or len(pwd) > 15:
        print("Insufficient length")
    elif re.search("\W|[^\x00-\xff]",pwd): 
        print("invalid pwd")
    elif re.match("_",pwd): #查看是否有中文出现
        print("invalid pwd")
    else:
        if Number.search(pwd):
            type += 1
        if Lower_case.search(pwd):
            type += 1
        if Upper_case.search(pwd):
            type += 1
        if others.search(pwd):
            type += 1
        if type < 3:
            print("weak pwd")
        if type == 3:
            print("midum  pwd")
        if type == 4:
            print("strong pwd")
   
jduge("daMASD_1")  

代码比较粗糙

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值