使用re模块时需要先导入re模块

  • 参数:

    • pattern:正则匹配规则
    • string:需要进行匹配的字符串
    • flags

      一、findall()的用法

  • 格式:findall(pattern, string, flags=0)

  • findall()返回值:
    • 列表形式
    • 所有符合匹配的结果都会写入列表中返回
    • 只有一个返回值列表
      1. import re
      2. pattern = '\d\w'
      3. string = '1e1r1s4w'
      4. result = re.findall(pattern, string)
      5. print(result)
      6. # 结果是:['1e', '1r', '1s', '4w']

二、match()和search()的用法

格式:match/search(pattern, string, flags)

  • search/match()的返回值:

    • 只返回符合匹配规则的第一个结果,后边符合的不返回
    • 返回值是一个对象类型,并且写着符合匹配结果在字符串中的下标范围
    • 如果匹配上返回一个匹配值对象,如果没有匹配上返回为None
    • 使用group()从匹配的对象中获取匹配到的字符串片段
      1. import re
      2. pattern = '\d\w'
      3. string = '1e1r1s4w'
      4. result1 = re.match(pattern, string)
      5. print(result1)
      6. print(result1.group())
      7. result2 = re.search(pattern, string)
      8. print(result2.group())
      9. print(result2)
      10. # 结果是:
      11. # <re.Match object; span=(0, 2), match='1e'>
      12. # 1e
      13. # 1e
      14. # <re.Match object; span=(0, 2), match='1e'>
  • search和match用法的区别:
    match在匹配上默认在匹配结果前加上^,即必须以匹配规则作为开头,
    search匹配没有这个要求,match相当于在search的匹配规则上加上^

    1. import re
    2. pattern = '\d\w\s'
    3. string = '%^2e 2343452322w 345a '
    4. result = re.search(pattern, string)
    5. print(result)
    6. result1 = re.match(pattern, string)
    7. print(result1)
    8. # 打印结果:
    9. # <re.Match object; span=(2, 5), match='2e '>
    10. # None

三、sub()和subn()用法

sub()和subn()都用于替换字符串中的内容

sub()

  • 格式:re.sub(pattern, 替换内容, string, count, flags)
  • 替换的内容是pattern匹配到的所有结果全部替换成替换内容
  • count表示当匹配到多个结果的时候可以替换几次
  • 返回值:替换后的字符串内容

    subn()

  • 格式:subn(pattern, 替换的内容,string,count, flags)

  • 返回值:(替换后的字符串,替换的次数)
  1. pattern = '\w\d.{2}'
  2. string = 'w2er 23wew2er1'
  3. str1 = string.replace('ew', 'mm')
  4. print(str1)
  5. # 普通字符串的内容替换
  6. result = re.sub(pattern, 'H', string, 2)
  7. print(result)
  8. result1 = re.subn(pattern, 'H', string, 2)
  9. print(result1)
  10. # subn()返回的结果是替换后的字符串和替换的次数组成的元组
  11. # subn和sub的区别在于subn返回值是一个元组,并且元组中包括替换的次数,sub没有替换次数
  12. '''
  13. # 结果是:
  14. w2er 23wmm2er1
  15. H Hw2er1
  16. ('H Hw2er1', 2)
  17. '''
  1. <a name="u6qRN"></a>
  2. ### 四、split()
  3. split()用于字符串切割
  4. - 格式为:re.split(pattern, string, maxsplit=0, flags=0)
  5. - 返回值:以列表的形式返回切割后剩余的字符串
  6. ```python
  7. import re
  8. pattern = '\w\d.{2}'
  9. string = 'w2er 23wew2er1'
  10. result2 = re.split(pattern, string, maxsplit=2)
  11. print(result2)
  12. # 打印结果:['', ' ', 'w2er1']

五、进阶用法:爬虫和自动化运维

(一)、re.compile()用法(时间上节省)

  • 格式:re.compile(pattern)
  • re.compile()是把匹配的规则设置成为通用的匹配规则模版,可以多次重复使用
  • 再把获得的模版结果用到上边的几个式子中
  • 这个模版用于重复使用时来节省时间,但是单次使用时不会节省时间
  1. import re
  2. re_compile = re.compile(pattern)
  3. # re.compile(匹配规则)获取的是通用的匹配规则模版,这个模版用于重复使用时来节省时间,但是单次使用时不会节省时间
  4. print(re_compile)
  5. result = re.search(re_compile, string)
  6. print(result.group())
  7. '''
  8. 结果是:
  9. re.compile('\\w\\d.{2}')
  10. w2er
  11. '''

(二)、finditer()的用法(空间上节省)

  • 格式为:re.finditer(pattern, string, flags=0)
  • 当匹配的结果比较少的时候用findall(),但是当匹配的结果比较大的时候必须用finditer(),可以节省内存
  • 通过finditer()返回的结果是一个可迭代对象,通过for循环可以获取每一个匹配的对象,再通过group()获取到每一个匹配的字符
  1. import re
  2. pattern = '\w\d.'
  3. string = 's3ed3de3shoihuiuhj;klnhjghcugiopi[;kbjd3sd2sf4sf5swsdfskghj3sj3sj4dja5s'
  4. result = re.finditer(pattern, string)
  5. print(result)
  6. for i in result:
  7. print(i.group())
  8. '''
  9. <callable_iterator object at 0x105f7afd0>
  10. s3e
  11. d3d
  12. e3s
  13. d3s
  14. d2s
  15. f4s
  16. f5s
  17. j3s
  18. j3s
  19. j4d
  20. a5s
  21. '''

所有空间效率的都伴随着时间效率的提高

六、分组优先原则

分组优先:是在正则表达式中通过()来实现分组,当匹配的字符串后显示的不是全部匹配成功的字符串,
而只是匹配括号内匹配上的结果

(一)、findall()中出现

  • 分组优先只会出现自findall()中,不会出现在search和match中
  • 取消分组优先:在正则表达式的括号内最前边加上”?:”即可取消分组优先 ```python import re pattern = ‘www.(baidu|jinritoutiao).com’

    当正则表达式中使用()进行分组后,通过findall()获取的结果是括号内匹配上的内容,而不是全部匹配上的内容

    分组优先原则

    string = ‘www.baidu.com’ result = re.findall(pattern, string) print(result) pattern = ‘www.(?:baidu|jinritoutiao).com’

    在括号中第一个位置加上?:可以取消分组优先,显示全部的内容

    string = ‘www.baidu.com’ result = re.findall(pattern, string) print(result) pattern = ‘www.baidu.com|www.jinritoutiao.com’

    普通的用法

string = ‘www.baidu.com’ result = re.findall(pattern, string) print(result) ‘’’ 结果是: [‘baidu’] [‘www.baidu.com’] [‘www.baidu.com’]

‘’’

  1. <a name="NtPEw"></a>
  2. #### (二)、在split()中的分组优先使用
  3. 在split()切割中会把符合匹配的规则的字符切割掉,返回值中不包括这些内容,可以给正则表达式添加()使用分组优先原则<br />,使得切割的内容也在返回值中显示
  4. ```python
  5. pattern = '\d+'
  6. string = 'alex100taibai20peiqi69'
  7. result = re.split(pattern, string)
  8. # 不使用分组优先原则切割掉的内容不会显示
  9. print(result)
  10. pattern = '(\d+)'
  11. # 在正则中通过()使用分组优先的原则,可以在切割的时候把正常情况下切割掉的内容正常显示出来
  12. string = 'alex100taibai20peiqi69'
  13. result = re.split(pattern, string)
  14. print(result)
  15. '''
  16. 结果是:
  17. ['alex', 'taibai', 'peiqi', '']
  18. ['alex', '100', 'taibai', '20', 'peiqi', '69', '']
  19. '''

(三)、在group()中使用分组优先

当查询到结果后通过group()可以显示匹配到的字符,当pattern存在多个group()时,在返回的结果中可以通过group(num)来获取每一个group()匹配到的结果
group()中不写数字获取的是匹配的所有数据,当写1的时候获取的是第一个group匹配的内容,2获取的是第二个group匹配的内容,以此类推。

  1. pattern = '\d(\.\d+)(\.\d+)(\.\d+)(\.\d+)(\.\d+)'
  2. string = '1.2.3.4.5.6.7'
  3. result = re.search(pattern, string)
  4. print(result)
  5. print(result.group())
  6. print(result.group(1))
  7. print(result.group(2))
  8. print(result.group(3))
  9. print(result.group(4))
  10. print(result.group(5))
  11. '''
  12. 结果是:
  13. 1.2.3.4.5.6
  14. .2
  15. .3
  16. .4
  17. .5
  18. .6
  19. '''

(四)、html标签分组命名匹配

html中标签名是前后对应的,在html中匹配标签内的内容,同时确保前后标签的名字是保持一致的,一共两种方式:

(一)、使用分组命名方式
  • 格式为:pattern = r’<(?P)\w+>(\w+)</(?P=name)>’
  • 注意:前边’<(?P\w+)>’是定义好标签的名字;后边</(?P=name)>是使用前边定义好的名字,第二个尖括号中必须加上’/‘。

    1. '''分组命名'''
    2. pattern = r'<(?P<name>\w+)>(\w+)</(?P=name)>'
    3. # 规范的格式为:前:<(?P<name>正则表达式)> 后: </(?P=name)>
    4. string = '<p>这是一个p标签</p>'
    5. result = re.search(pattern, string)
    6. print(result.group())
    7. # 通过分组命名的方式来规范匹配的前后标签名一致
    8. # 结果是:<p>这是一个p标签</p>
  • 可以给每一个组进行命名,不局限于标签命名,然后把每一个组的命名放到group(name)中打印

    1. pattern = r'<(?P<tag>\w+)>(?P<content>\w+)</(?P=tag)>'
    2. string = r'<a>这是一个超链接</a>'
    3. result = re.search(pattern, string)
    4. print(result)
    5. print(result.group('tag'))
    6. print(result.group('content'))
    7. # 可以为每一个分组进行命名,然后把每一组的名字放到group中打印每一个组的内容

(二)、使用\1来实现标签前后一致
  • 格式:<(\W+)>(\w+)<(/\1)>
  • 注意:前边的标签:<(\w+)>, 后边的标签直接使用</\1>来对应

    与分组命名相比,第二种方式更为简洁,但是这种方式有一个缺点:当匹配的规则非常多的时候,\1很容易使开发者混乱,搞不清楚对应那个开头。

  1. pattern = r'<(\w+)>(\w+)</\1>'
  2. # 在后边对应的标签上写入</\1>即可以保证后边的标签名和前边的一致,但是这种方式当匹配的正则很多的情况下容易忘记
  3. string = '<p>这是一个p标签</p>'
  4. result = re.search(pattern, string)
  5. print(result.group())
  6. # 结果是:
  7. <p>这是一个p标签</p>