zoukankan      html  css  js  c++  java
  • 爬虫入门【4】正则表达式用法简介

    特殊字符的含义

    首先推荐使用r'string'来定义字符,免去转义字符的影响。
    
    #'.',点号,在默认模式中,匹配任何一个字符,除了新的行newline。如果DOTALL标记指定了,那么还可以匹配newline。
    # '^',匹配字符串的开始
    # '$',匹配字符串的结束。比如foo匹配foo或者foobar,但是foo$只能匹配到foo。
    # '*',匹配0个或者多个字符,比如ab*,可以匹配a,ab,abbbb等
    # '+',匹配1个或者多个字符,比如ab+,可以匹配ab,或者abbbb
    # '?',匹配0或者1个字符,比如ab?只能匹配a或者ab。
    #贪婪模式,*?+,都是贪婪模式的,会尽可能多的匹配字符,在后面加上一个?则会变为非贪婪模式,尽可能匹配少的字符。
    #我们一般用非贪婪模式。
    
    # {m},指定匹配的数量,比如a{6}表示将匹配6个a字符,而不是5个,准确匹配。
    # {m,n},匹配在m~n个字符之间,包含m和n,比如a{3,5}将匹配3-5个a字符,一般会取上限来匹配。
    # 如果不指定m或者n,则表示没有上限,下限不能低于0个
    # {m,n}?,非贪婪模式的匹配,尽可能匹配少,取下限m来匹配。
    
    # [],用于创造一个字符的集合,字符可以单独出现或者使用0-9,a-z这种格式。
    # 比如:[amk]会匹配a,m或者k字符。[a-z]将会匹配a-z之间的任何一个字符。[0-5][0-9]匹配从00-59的所有字符。
    # 如果在[]中包含一个特殊字符的集合,比如[(+*)],这些特殊字符将会失去其特殊含义,只匹配字面意义,'('')''+''*'。
    # 如果在[]的开始有一个'^',比如[^5],将会匹配任何一个不是5的字符。
    
    # '|',A|B,AB是任意的RE表达式,可以匹配A或者B
    # (...),括号内的表达式将作为分组,从表达式左边开始每遇到一个分组的左括号,编号+1。分组表达式作为一个整体,可以后接数量词。
    # 比如,(abc){2}匹配abcabc,a(123|456)c匹配a456c或者a123c。
    # (?P<name>...),分组,除了原有的编号外,指定一个额外的别名,比如:(?P<id>abc){2},可以匹配abcabc,通过.'id'来访问。
    # <number>,引用编号为<number>的分组匹配到的字符串。比如(d)abc1,可以匹配1abc1,或者5abc5
    # (?P=name),引用别名为<name>的分组匹配到的字符串,比如(?P<id>d)abc(?P=id),可以匹配1abc1,5abc5等。
    
    # d,表示数字,0-9之间的一个,比如adc,可以匹配a1c;
    # D,表示非数字,也可以用[^d]来代替,
    # s,表示空白字符
    # S,表示非空白字符
    # w,表示单词字符,[A-Za-z0-9_]
    # W,表示非单词字符。
    # A,仅匹配字符串的开头,Aabc可以匹配abc。
    # ,仅匹配字符串结尾,abc,匹配abc
    

    Re模块

    介绍常用的几个方法

    #首先要导入re模块
    import re
    

    re.compile(pattern,flags=0)

    #将原生字符串对象传到compile方法中,可以获得一个pattern匹配模式
    pattern=re.compile(r'hello')
    #这个pattern可以用于进一步的匹配
    #flag参数,指匹配模式,可以选则
    re.I#忽略大小写
    re.M#多行模式
    re.S#点任意匹配,
    re.L#
    re.U
    re.X#详细模式,这个模式下正则表达式可以是多行,忽略空白字符,并可以加入注释。
    

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

    match方法会从要匹配的string的开头开始,尝试匹配pattern,一直向后,如果遇到无法匹配的字符,就返回None,如果匹配未结束已经到达string的末尾也会返回None,表示匹配失败。匹配成功会返回True,以及匹配到的内容的group。
    举个例子:(来自http://cuiqingcai.com/977.html)

    pattern=re.compile(r'hello')
    result1=re.match(pattern,'hello')
    result2=re.match(pattern,'helloo world')
    result3=re.match(pattern,'helo world')
    result4=re.match(pattern,'hello world')
    
    if result1:
        print(result1.group())
    else:
        print('1匹配失败!')
    if result2:
        print(result2.group())
    else:
        print('2匹配失败!')
    if result3:
        print(result3.group())
    else:
        print('3匹配失败!')
    if result4:
        print(result4.group())
    else:
        print('4匹配失败!')
    
    
    hello
    hello
    3匹配失败!
    hello
    
    #对于返回的这个结果,我们再通过一个例子来了解一下:
    import re
    m=re.match(r'(w+) (w+)(?P<sign>.*)','hello world!')#单词+空格+单词+任意字符
    
    print(m.string)#获取匹配时使用的文本
    print(m.re)#获取匹配时使用的pattern对象
    print(m.pos)#文本中开始搜索的位置
    print(m.endpos)#返回结束搜索的位置
    print(m.lastindex)#最后一个被捕获的分组在文本中的索引
    print(m.lastgroup)#最后一个最捕获的分组的别名
    print(m.group())#获得一个或多个分组截获的字符串,如果指定多个参数,将会以元祖形式返回
    print(m.group(1,2))#指定多个参数
    print(m.groups())#以元组形式返回所有分组截获的字符串
    print(m.groupdict())#返回具有别名的组的别名为Key,字符串为value的字典,不包含别名的组不统计
    print(m.start(2))#返回指定的组截获的子串在string中的起始索引
    print(m.end(2))#返回指定的组在string中的结束索引
    print(m.span(2))#返回(start(group),end(group))
    
    hello world!
    re.compile('(\w+) (\w+)(?P<sign>.*)')
    0
    12
    3
    sign
    hello world!
    ('hello', 'world')
    ('hello', 'world', '!')
    {'sign': '!'}
    6
    11
    (6, 11)
    

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

    类似与match方法,但是match会检测re是不是在string的开始位置就能够匹配到,而search会扫描整个string来匹配。match方法只有在0位置匹配成功的话才会返回,如果不是开始i位置,即使后面由匹配,也会返回None。

    import re
    pattern=re.compile(r'world')
    match=re.search(pattern,'hello world!')
    if match:
        print(match.group())
    
    world
    

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

    re.split(pattern, string, maxsplit=0, flags=0)

    将string按照匹配的子串分割后返回列表,maxsplit参数指定最大分割次数,不指定的话会全部分割。

    import re
    pattern=re.compile(r'd+')
    split=re.split(pattern,'one1two2three3four4')
    print(split)
    
    ['one', 'two', 'three', 'four', '']
    

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

    搜索string,以列表的形式返回全部能匹配的子串。

    import re
    pattern = re.compile(r'd+')
    print(re.findall(pattern,'one1two23three3four4'))
    
    ['1', '23', '3', '4']
    

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

    搜索string,返回一个顺序访问每一个匹配结果的迭代器

    import re
    pattern=re.compile(r'd+')
    for m in re.finditer(pattern,'one1two23three3four4'):
        print(m.group())
    
    1
    23
    3
    4
    

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

    使用repl替换string中的每一个匹配的子串后返回替换的字符串。
    repl可以是一个方法,这个方法应该只接受一个match对象作为参数,并且返回一个字符串用于替换。
    count可以指定最多替换次数,不指定的话就全部替换。

    import re
    pattern=re.compile(r'(w+) (w+)')
    string='i say, hello world!'
    print(re.sub(pattern,r'2 1',string))
    
    def func(m):
        return m.group(1).title()+' '+m.group(2).title()
    print(re.sub(pattern,func,string))
    
    say i, world hello!
    I Say, Hello World!
    

    Pattern,正则表达式对象

    上面介绍的所有方法都适用于pattern。

    如果您觉得感兴趣的话,可以添加我的微信公众号:一步一步学Python

  • 相关阅读:
    Java类加载器回顾
    2018第24周总结
    JUC类图
    CopyOnWrite 策略
    Python导入模块的几种姿势
    查看linux接口进出口流量的命令;linux 网络监控;流量监控
    jenkins修改日志级别方法
    top命令查看线程信息和jstack使用介绍
    How to force immediate stop of threads in Jmeter servers如何在jmeter执行完,立即停止jmeter
    pycharm支持react
  • 原文地址:https://www.cnblogs.com/xingzhui/p/7856448.html
Copyright © 2011-2022 走看看