18 - 正则表达式

.正则表达式

1.概念

  • 正则表达式是一个特殊的字符序列,用来表达对字符串的一种过滤逻辑。通常被用来检索、替换那些符合某个模式(规则)的文本。

2.作用和特点

  • 给定一个正则表达式和另一个字符串,我们可以达到如下的目的:
    1. 给定的字符串是否符合正则表达式的过滤逻辑(称作'匹配')
    2. 可以通过正则表达式,从字符串中获取我们想要的特定部分

3.re模块

  • 使用re模块。re 模块使 Python 语言拥有全部的正则表达式功能。(系统内置模块)
  • 通过使用re模块中的方法结合正则表达式,可以实现相关功能

4.re模块中的方法

1)match()

  • re.match()尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回None。

  • 格式:

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

    参数 描述
    pattern 匹配的正则表达式
    string 要匹配的字符串。
    flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
    import re
    m = 'abcdef'
    result = re.match('ab',m)
    print(result)  #<_sre.SRE_Match object; span=(0, 2), match='ab'>
    result2 = re.match('cde',m)
    print(result2)  #None
    

说明:就是用pattern去string中匹配,如果开头就匹配成功,则返回span -- 匹配的位置,match -- string中满足条件的子串;不成功则返回None

2)search()

  • re.search()扫描整个字符串并返回第一个成功的匹配,只要匹配成功就不找了。

  • 格式:

    re.search(pattern, string, flags=0)

    m = 'abcdef'
    result = re.search('cd',m)
    print(result)  #<_sre.SRE_Match object; span=(2, 4), match='cd'>
    

3)findall()

  • 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。

    m = 'abc4d kdfkle2o9lfls'
    result = re.findall('[a-z][0-9][a-z]',m)
    print(result)  #['c4d', 'e2o']
    

4)span()group()groups()

  • span():用来得到用search或者match查找到返回的结果中位置(即span = (...))

    m = 'abcdef'
    result = re.search('cd',m)
    print(result.span()) #(2, 4) 左闭右开
    
  • group():提取到匹配的内容,经常与正则的分组()一起使用,参数为数组(分组的第几组)

    print(result.group()) #cd
    

5)sub()

  • sub():相当于替换,将源字符串用正则匹配到的内容,用新的字符串去替换

  • 格式:sub(正则表达式,'新内容',string)

    import re
    str = 'java = 100,python = 100'
    result = re.sub(r'\d+','90',str)
    print(result)   #java = 90,python = 90
    
  • 格式:sub(正则表达式,函数,string)

    import re
    def func(temp):
    	num = temp.group()  #提取到匹配的内容
    	num = int(num) + 1
    	return str(num)
    str = 'java = 99,python = 98'
    result = re.sub(r'\d+',func,str)  #提取正则的返回值中的匹配内容,用来替换
    print(result)
    

6)split()

  • 用来切割字符串,分割的依据是正则表达式匹配的内容

    import re
    result = re.split(r'[,:]','java:99,python:100')  #以逗号或者冒号来分割
    print(result)  #['java', '99', 'python', '100']
    

5.正则相关符号

  • 通过上面的例题我们只能做到匹配查询某一个特定的字符串,但是假如现在有这样的需求:

    msg = 'abc4d kdfkle2o9lfls'
    我们想要匹配到第一个是字母、第二个是数字、第三个是字母,满足这样的要求的字符串,那么就要用到正则的符号来帮我们做到条件过滤
    

上面我们用指定固定的字符串传给pattern参数来匹配过滤,但是pattern这里可以使用正则表达式得到我们想要筛选的字符串


特殊符号

  • 所谓特殊字符,就是一些有特殊含义的字符。若要匹配这些特殊字符,必须首先使字符"转义",即将反斜杠字符\ 放在它们前面。

    特殊字符 描述
    [] 用于表示一组字符,表示一个范围 (或者的关系)
    例如:[1234]表示只要满足当中的一个数字 。或者1或者2或者3或者4。要匹配 [,请使用 \[
    ( ) 将当中的子表达式当成一个整体来匹配,也有将字符串分成多组,按组的内容来进行匹配
    例如:`r'(qq
    [^ ] 如果[]中第一个字符是^,则标识的是一个补集
    例如: [^0-9]表示除了数字外的字符
    [0-9] 匹配任何一个数字
    [a-z] 匹配任何一个小写字母
    [A-Z] 匹配任何一个大写字母
    例如:可以连用[a-zA-Z]
    [a-zA-Z0-9] 匹配任何一个字母及数字
    \d 匹配任意一个数字字符
    \D 匹配一个非数字字符
    \s 匹配任意一个空白字符 (等价于[\t\n\r\f]
    \S 匹配任意一个非空白字符 (等价与[^\s]
    \w 匹配任意一个字母数字下划线
    \W 匹配任意一个非字母数字及下划线
    . 匹配除换行符 \n 之外的任何单字符
    注意为了防止转义,发挥.的正则的作用:要匹配 . ,请使用 \. ;如果不想就想匹配.,则不加
    **` `**
    [\u4e00-\u9fa5] 匹配纯中文

注意:为了防止正则中的\符号被转义,可以选择在\前再加上\,如'txt\\b'; `

或者可选择在正则字符串之前加上 r ,如:r'\s\b.'


限定符

  • 限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有 ***** 或 +?{n}{n,}{n,m} 共6种。

    限定符 描述
    ***** 匹配前面的子表达式0次或多次 >=0
    例如,'[a-z][0-9]+'表示第一个为小写字母,第二个为数字、可以出现0次或者多次,都可以匹配----x9z983s * 等价于{0,}
    + **匹配前面的子表达式1次或多次 ** >=1
    例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。
    ? 匹配前面的子表达式0次或1次 0或1
    例如,"do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "do" 。? 等价于 {0,1}。
    {n} 匹配确定的 n 次 =n
    例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。 (n 是一个非负整数)
    {n,} 至少匹配n 次 >=n
    例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。 (n 是一个非负整数)
    {n,m} 最少匹配 n 次且最多匹配 m 次 [n,m]
    例如,"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。 (m 和 n 均为非负整数,其中n <= m)

限定符加在想要限定的字符后面


定位符

  • 定位符用来描述字符串或单词的边界,^$ 分别指字符串的开始与结束,\b 描述单词的前或后边界,\B 表示非单词边界。

    定位符 描述
    ^ 匹配输入字符串的开始位置
    例如:^h匹配以h开头;在方括号表达式中时,它表示不接受该字符集合,例如[^0-9]匹配除了数字以外的数据。要匹配 ^ 字符本身,请使用 `^。
    $ 匹配输入字符串的结尾位置
    例如:'^[^0][0-9]{4}$'表示用此正则去字符串从头到尾匹配,也就是说整个字符串从头到尾都要满足正则规定的条件才能符合。[a-z][0-9]{5,9}$表示只要开始有匹配的,就必须匹配到字符串的结尾
    \b 匹配一个单词边界,即字与空格间的位置
    比如'aa.py u_u.txt z2.png bb3.py apy.doc'要在当中找出.py结尾的文件全名。则用result = re.findall('\w+.py\\b',m)'
    \B 非单词边界匹配

6.正则分组以及为分组起名

  • 我们用正则匹配一个子字符串,当后面还要匹配同种规则的子串时,就可以为这些相同的规则匹配的子字符串分组起名。

  • 为分组取名

    定义格式:(?P<名字>正则) 使用时:(?P=名字)

    #现在需要匹配找到msg这种的标签类型(标签要成对,标签中间的内容可有可无)
    import re
    msg = '<html><h1>dks</h1></html>'  #通过()将字符串分组,<html>为一组,<h1>为一组,标签中间的内容为一组...
    result = re.match(r'<(?P<name1>\w+)><(?P<name2>\w+)>(.*)</(?P=name2)></(?P=name1)>',msg)
    print(result)
    
  • 直接使用数字

    ()为字符串分好组后,可以使用数字来对分组中用正则匹配到的子串访问

    #不取名时,直接使用下标引用分组匹配的内容
    result = re.match(r'<(\w+)><(\w+)>(.*)</\2></\1>',msg)
    print(result.group(1),result.group(2)) # html h1
    

7.贪婪和非贪婪

  • python中数量词默认是贪婪的----比如:*+?等,这些表示正则数量的限定

  • 贪婪模式:总是尝试匹配尽可能多满足条件的字符

  • 非贪婪模式:总是尝试匹配尽可能少满足条件的字符

    *,?,+,{m,n}数量词后面加上 ?使贪婪变成非贪婪。

    import re
    msg = 'abc123dd'
    result = re.match(r'abc(\d+)',msg) #本来abc后匹配到1就可以满足正则(正则表示>=1个数字即可),但是贪婪模式就是尽可能多的匹配,把后面的数字123全匹配完,可是满足的
    print(result.group())  #abc123
    
    result1 = re.match(r'abc(\d+?)',msg)
    print(result1.group())  #abc1
    

8.正则表达式练习

  • 用户名匹配:由数字、大小写字母、下划线_和中横线-组成,长度为4到14位,并且不能以数字开头。

    r'^\D[a-z0-9A-Z_\-]{3,13}', 'sH_8'
    
  • 匹配邮箱

    r'^([A-Za-z0-9_\-\.])+@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$
    
  • 匹配手机号

    r'^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\d{8}$'
    
  • 匹配身份证号。

    r'^[1-9]\d{5}(18|19|20|)\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$'
    
  • 匹配URL地址

    r'((ht|f)tps?):\/\/([\w\-]+(\.[\w\-]+)*\/)*[\w\-]+(\.[\w\-]+)*\/?(\?([\w\-\.,@?^=%&:\/~\+#]*)+)?'
    
  • 匹配QQ号

    r'^[1-9][0-9]{4,10}$'
    
  • 匹配微信号

    r'^[a-zA-Z]([-_a-zA-Z0-9]{5,19})+$'
    
  • 匹配车牌号

    r'^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}[A-Z0-9]{4}[A-Z0-9挂学警港澳]
    
posted @ 2021-10-14 19:25  深藏Bluee  阅读(96)  评论(0)    收藏  举报