正则表达式小结(Python)

正则表达式(Regular Expression)是强大、便捷、高效的文本处理工具。
本文是《精通正则表达式》的读书笔记和以前学正则时候的笔记汇总,一些概念性的东西本文并没有讲到,具体可以看看这本书。

正则引擎主要可以分为基本不同的两大类:一种是DFA(确定性有穷自动机),另一种是NFA(非确定性有穷自动 机)。正则引擎可以粗略地分为3类:DFA、传统型NFA、POSIX NFA,基本涵盖了现在主流的大部分程序,Python中的正则属于传统NFA型,本文中只讲Python中的正则。

NFA引擎最重要的性质是,它会依次处理各个子表达式或组成元素,遇到需要在两个可能成功的可能中进行选择的时候,它会选择其一,同时记住另一个,以备稍后可能的需要。
回溯就像是在道路的每个分岔口留下一小堆面包屑。如果走了死路,就可以照原路返回,直到遇见面包屑标示的尚未尝试过的道路。如果那条路也走不通,你可以继续返回,找到下一堆面包屑,如此重复,直到找到出路,或者走完所有没有尝试过的路。

总的来说DFA和NFA的明显区别之一在于效率,正如上面说到的,由于DFA没有回溯,因此看起来在某些情况下会比NFA来得更快,但是在真正使用 中,DFA需要进行预编译才能获得更好效果,因为DFA的匹配方式需要更多的内存和时间,

应用场景

  • 特定规律字符串的查找替换切割等
  • 邮箱格式、url等格式的验证
  • 爬虫项目、提取特定的有效内容
  • 很多应用的配置文件

基本使用

  • 说明:正则是通过re模块提供支持的
  • 相关函数:

    • match:从开头进行匹配找到就立即返回正则结果对象,没有就返回None
    • serach:匹配全部内容,任意位置,只要找到,立即返回正则结果对象,没有就返回None

    • findall(pattern, string, flags=0),匹配所有内容,前两个返回的是对象,这个返回的是匹配结果组成的列表,没有返回None
      flags有几种不同的意义,如下:
      re.I (re.IGNORECASE): 忽略大小写
      re.M(re.MULTILINE) :多行匹配,否则按照一行匹配
      re.S :使.可以匹配到\n

    
    # 第一个参数是正则表达式,第二个参数是需要匹配的字符串
    
    f = re.findall('abc', 'abcsdisuoiabcsjdklsjabc')
    • compile:根据字符串生成正则表达式的对象,生成的是正则!用于特定正则匹配,通过match、search、findall匹配
    
    # 根据字符串生成正则表达式的对象(需要匹配的字符串),用于正则匹配
    
    c = re.compile('abc')
    
    # 然后进行特定正则匹配
    
    m = c.search('abcdefghijklmn')
    
    # 分组后可以用m.group()来获取分组内容,不加参数是所有,加参数是获取指定
    

其实就是将re模块中的match、search、findall方法的处理过程分为了两步完成。

  • re.sub(pattern, repl, string) 两个可选参数:count, flags
    必选参数:
    • pattern,表示正则中的模式字符串
      【注】反斜杠加数字(\N),则对应着匹配的组(matched group)
      比如\6,表示匹配前面pattern中的第6个group
      意味着,pattern中,前面肯定是存在对应的,第6个group,然后你后面也才能去引用
    # 正则中的\1:表示前面第一个小括号匹配的结果
    # 分组默认名称是\1,\2
    # c = re.compile(r'<([a-z]+)><([a-z]+)>\w*</\2></\1>')
    # c = re.compile(r'<(?P<hello>[a-z]+)><(?P<world>[a-z]+)>\w*</\2></\1>')
    # 可以给指定的分组起个名字
    c = re.compile(r'<(?P<hello>[a-z]+)><(?P<world>[a-z]+)>\w*</(?P=world)></(?P=hello)>')
    s = c.search('xxx<div><a>百度一下</a></div>yyy')
    if s:
      print('ok')
      print(s)
      # group中也可以填参数,获取指定分组的匹配内容
      print(s.group())
  • 第二个参数:repl
    repl,就是replacement,被替换的字符串的意思。
    repl可以是字符串,也可以是函数。

    • 如果是字符串,其中的任何反斜杠转义字符,都会被处理的。
      \n:会被处理为对应的换行符;
      \r:会被处理为回车符;
      其他不能识别的转移字符,则只是被识别为普通的字符:
      比如\j,会被处理为j这个字母本身;
      反斜杠加g以及中括号内一个名字,即 \g < name >,对应着命了名的组

    第三个参数:string
    string,即表示要被处理,要被替换的那个string字符串。

正则表达式, 替换内容, 字符串

支持的元字符,以及这些元字符的意义,通常称为正则表达式的流派

元字符

在理解正则的时候最好养成按照字符来理解正则表达式的习惯,比如 ^cat,不要理解成匹配以cat开头的行,而要理解成匹配的是以c作为一行的第一个字符,紧接一个a,紧接一个t的文本,这两种理解的结果并没有差异,但按照字符来解读更易于明白遇到的正则表达式的内部逻辑。

脱字符号^ 和美元符号 $的特别之处在于它们匹配的是一个位置,而不是具体的文本,这种匹配位置的元字符也叫做锚点。

  • ^cat$
    文字意义:匹配的条件是开始是行开头,然后是字母cat,最后是行末尾三部分。
    应用意义:只包含cat的行,没有多余的单词、空白字符。
  • ^$
    文字意义:匹配的条件是,行开头和行末尾。
    应用意义:空行(没有任何字符,包括空白字符)
  • ^
    文字意义:匹配条件是行的开头
    应用意义:无意义!因为每一行都有开头,每一行都能匹配到。

其余常见元字符:

   . : 除换行以外所有字符
    [] :[aoe] [a-w] 匹配集合中任意一个字符
    \d :(digit)数字  [0-9]
    \D : 非数字
    \w :(word)数字、字母、下划线、中文
    \W : 非\w
    \s :(space)所有的空白字符
    \S : 非空白
数量修饰:
   * : 任意多次  >=0
    + : 至少1次   >=1
    ? : 可有可无  0次或者1次
    {m} :固定m次
    {m,} :至少m次
    {m,n} :m~n次
边界:
   \b \B 
    $ : 以某某结尾 
    ^ : 以某某开头
- 分组匹配
   |:表示或,具有最低的优先级
   ():用于表示一个整体,可以确定优先级,在python正则中也表示捕获,
  会只返回捕获的内容,只用于分组的话可以用非捕获型括号(?:  ),这时候括号就只用于分组了,
   正则中的`\1`表示前面第一个小括号匹配的结果,以此类推
命名捕获:

python的引擎能为捕获的内容命名。Python的语法是(?P<name>...),如果要在正则表达式内部引用捕获的文本则使用(?P=name)

一些常用例子

  • 匹配IP地址
    分析:ip地址的每个字段都在0~255以内,且共有四个字段。

    完全匹配一个正确的ip地址的话,需要复杂的步骤,比如^(?:[01]?\d\d?|2[0-4]\d|25[0-5])\.(?:[01]?\d\d?|2[0-4]\d|25[0-5])\.(?:[01]?\d\d?|2[0-4]\d|25[0-5])\.(?:[01]?\d\d?|2[0-4]\d|25[0-5])$

    这样比较复杂,这个表达式只会匹配合法的ip地址,某些情况下,更合适的澡盆啊是不依赖正则表达式完成全部工作,比如可以用\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3},然后把几个数字变成程序中的变量,对这些变量再用其他程序进行验证。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值