zoukankan      html  css  js  c++  java
  • Python-正则表达式

    1、正则表达式:

      概述:

      正则表达式:RegularExpression,缩写regex,regexp,RE等。是处理文本极为重要的技术,用它可以对字符串按照某种规则进行检索,替换。

      分类:

        1、BRE

          基本正则表达式,grep, sed,vi,等软件支持,vim有扩展

        2、ERE

          扩展正则比倒是是,ergep(grep -E),sed -r等

        3、PCRE

          几乎所有高级语言都是PCRE的方言Python从1.6开始使用正则表达式引擎。

    2、基本语法:

      元字符:(匹配一位)

        . 匹配除换行符外的任意一个字符
    [abc]:字符集合,只能表示一个字符位置
    [^abc]
    [a-z]
    [^a-z]
    :匹配单词的边间, b 找b开头, [abc] :a或b或c开头,适合英文
    B:不匹配单词的边界 tB 含t,但不以t结尾, Bb 不以b开头,但含有b
    d:[0-9]匹配一位数字
    D:[^0-9]一位非数字
    s:[ f v]匹配1位空白字符---空格,分页,回车,换行,制表,在win中注意
    S:一位非空白字符
    w:匹配[a-zA-Z0-9_],包括中文,,注意还有个下划线
    W:之外的字符,win中可能是 会被匹配(查一下)

      转义:

        凡是在正则表达式中有特殊意义的符号,如果想使用它本意,请使用   转 义.

        反斜杆自身,得使用 \

         , 还是转义后代表回车,换行  

      重复:(贪婪模式)

        *:任意次
    +:至少一次
    ?:0,1次
    {n}:n次
    {n,}
    {n,m}
       x | y: 匹配x 或者y
     捕获:
       (pattern):使用小括号指定一个子表达式,也叫分组捕获后会自动分配组号,从1 开始,可以改变优先级
       数字:匹配对应的分组 如:(very)1 ----> veryvery
       (?:pattern):仅仅改变优先级,并不分组(或者取消分组)
       (?P<name>exp) (?P'name'exp) 分组捕获,但是可以通过name访问分组
     零宽断言:
       (?=exp):如:f(?=oo) f后面一定有oo出现,但是不显示oo,只显示f
       (?<=exp):如:(?<=f)ood ood之前一定有f,但是不显示f,只显示ood
     负向零宽断言:
       (?!exp):如:d{3}(?!d)匹配三位数字,断言3位数字后一定不能是数字
       (?<!exp):如: (?<!f)ood ood的左边一定不是f  
     注释:
       (?#comment) : f(?=oo)(?#.....)
     
      注:
        断言不会被捕获,不会占用分组,因为本身并不是分组,不会match,所以更不会分组
        分组和捕获是同一个意思! 

      贪婪与非贪婪:

        默认是贪婪模式,也就是说尽量匹配更长的字符串

        非贪婪模式很简单,尽量少的匹配

        *?: 匹配任意次,但是尽可能少重复

        +?:匹配至少一次,但是尽可能少重复

        ??:匹配0次,或1次,但是尽可能少重复

        {n,}?:至少匹配n次,但是尽可能少重复

        {n,m}:至少匹配n次,之多m次,但是尽可能少重复

          可以看出左图:使用了非贪婪模式,也就是第二个verry 匹配到y就不往后走了,否则还会往后走,如右图

      引擎:

        IgnoreCase:忽略大小写 re.I

        Singleline:单行模式,可以匹配所有的字符,包括    re.S

        Multiline:多行模式,^ 行首,$行尾   re.M

        IgonrePatternWhitespace:忽略表达式中的空白字符,否则需要转义    re.X

        单行模式:  

          .  可以匹配所有的字符,包括换行符

          ^ 表示整个字符串的开头,$整个字符串的结尾

        多行模式:  

          .  可以匹配除换行符外所有的字符,包括换行符

          ^ 表示行的开头,$整个行的结尾

            开头: 后紧接着下一个字符,

            结尾: 前的一个字符

         注:注意字符串中看不见的换行符, 会影响 $测试,appe$ 只能匹配 appe       

            单行、多行一起用:
              如果是 点 看单行模式
              如果是 ^ 看多行模式
            如果都不选 , 点是冲不破 换行符的,$就是文件末尾
          默认模式:可以看做待匹配的文本是一行,不能看做多行,点号不能匹配换行符, ^ 和 $ 表示行首和行尾,而行行首行尾就是整个字符串的开头和结尾。
          单行模式:基本和默认模式一样,只是 点号终于可以匹配任意一个字符,包括换换行符,这时所有文本就是一个长长的只有一行的字符串,^就是这一行字符串的行首,$ 就是这一行的行尾
          多行模式:重新定义了行的概念,但不影响点号的行为, ^ 和 $ 还是行首行尾的意思,只不过因为多行模式可以识别换行符了,‘开始’指的是 后紧接着的下一个字符,,‘结束’指的是 前的字符,注意最后一行结尾可以没有
          简单讲:单行模式只影响点 号行为,多行模式重新定义行

      举例:选出含有ftp的链接,且文件类型是gz或者xz的文件,要求打印其文件名,文件名升序排列

    或者利用断言,直接取出来;

    3、python的正则表达式:

      python使用re模块提供正则表达式处理的能力

      常量:

    常量 说明
    re.M re.MULTILINE 多行模式
    re.S re.DOTALL 单行模式
    re.I re.IGNORECASE 忽略大小写
    re.X re.VERBOSE 忽略表达式中空白字符

            使用 | 位或,开启多中模式

      编译:

        re.complie( pattern, flags = 0)

        设定flags,编译模式,返回正则表达式对象regex

        pattern就是正则表达式字符创,flags是选项,正则表达式需要被编译,为了提高效率,这些编译后的结果被保存,下次使同样的pattern的时候,就不需要再次编译。

        re的其他方法为了提高效率都调用了编译方法,为了提高效率。  

      测试:

      1 import re
      2 
      3 s = '''bottle
    bag
    big
    apple'''
      4 
      5 ''' 
      6 match 使用  
      7 match 不管多行还是单行,只从开头查找,
      8         或,先编译,再指定的位置索引开始找,第一个字符匹配不上,就None,且只匹配一个'''
      9 print('{:*^{}}'.format('macth', 30))
     10 ''' 编译的match 和 非编译的match不是同一个match'''
     11 result = re.match('b', s)
     12 print(result) #  <re.Match object; span=(0, 1), match='b'>  返回一个match对象
     13 result = re.match('a', s)
     14 print(result) # None
     15 result = re.match('^a', s, re.M)
     16 print(result) # None
     17 result = re.match('^a', s, re.S,)
     18 print(result) # None
     19 
     20 print('{:*^{}}'.format('macth-compile', 30))
     21 # 现编译,然后使用正则表达式对象
     22 regex = re.compile('a')
     23 # print(regex) # re.compile('a')
     24 result = regex.match(s)
     25 print(result) # None
     26 result = regex.match(s, 15) # 把索引15 作为开始找
     27 print(result) # <re.Match object; span=(15, 16), match='a'>
     28 
     29 '''
     30 search 使用
     31 search(),从当前位置往后找,匹配第一个,之后不匹配了
     32 '''
     33 ''' 编译的serach和 非编译的search不是同一个search'''
     34 
     35 print('{:*^{}}'.format('search', 30))
     36 
     37 result = re.search('a', s)
     38 print(result) # <re.Match object; span=(8, 9), match='a'> 返回一个match 对象
     39 
     40 regex = re.compile('b')
     41 result = regex.search(s, 2)
     42 print(result) # <re.Match object; span=(7, 8), match='b'>
     43 
     44 regex = re.compile('^b', re.M)
     45 result = regex.search(s)
     46 print(1,result) # <re.Match object; span=(0, 1), match='b'>, 不管多少行,找到就返回
     47 
     48 result = regex.search(s, 5)
     49 print(2, result) # 2 <re.Match object; span=(7, 8), match='b'>
     50 
     51 '''
     52  fullmatch 的使用
     53  要完全匹配不能多, 不能少
     54  # fullmatch 把整个字符串包括在内,多行模式,换行符也算
     55 
     56 '''
     57 print('{:*^{}}'.format('fullmatch', 30))
     58 
     59 result = re.fullmatch('bag', s)
     60 print(result) # None
     61 
     62 regex = re.compile('bag')
     63 result = regex.fullmatch(s)
     64 print(result) # none
     65 
     66 regex = re.compile('bag')
     67 result = regex.fullmatch(s, 7)
     68 print(result) # none
     69 
     70 regex = re.compile('bag')
     71 result = regex.fullmatch(s, 7, 10)
     72 print(result) # <re.Match object; span=(7, 10), match='bag'>
     73 
     74 
     75 
     76 ''' 全文搜索  '''
     77 
     78 
     79 s = '''bottle
    bag
    big
    able'''
     80 
     81 '''
     82 findall 的使用,立即返回,全是元素字符串
     83 
     84 '''
     85 print('{:*^{}}'.format('findall', 30))
     86 
     87 result = re.findall('b', s)
     88 print(result) # ['b', 'b', 'b', 'b'],所用的都找到,返回列表
     89 
     90 regex = re.compile('^b')
     91 print(regex) # re.compile('^b')
     92 result = regex.findall(s)
     93 print(result) # ['b']
     94 
     95 regex = re.compile('^b', re.M)
     96 result = regex.findall(s, 7)
     97 print(result) # ['b', 'b']
     98 
     99 regex = re.compile('b', re.S)
    100 result = regex.findall(s)
    101 print(result) # ['b', 'b', 'b', 'b']
    102 
    103 regex = re.compile('^b', re.S)
    104 result = regex.findall(s)
    105 print(result) # ['b']
    106 
    107 regex = re.compile('^b', re.M)
    108 result = regex.findall(s, 7, 10)
    109 print(result) # ['b']
    110 
    111 
    112 '''
    113 finditer 方法
    114 
    115 '''
    116 print('{:*^{}}'.format('finditer', 30))
    117 
    118 regex = re.compile('^b', re.M)
    119 result = regex.finditer(s)
    120 for i in result:
    121     print(1, i) # match 对象
    122 # 1 <re.Match object; span=(0, 1), match='b'>
    123 # 1 <re.Match object; span=(7, 8), match='b'>
    124 # 1 <re.Match object; span=(11, 12), match='b'>
    125 print(result) # <callable_iterator object at 0x00000000021CFCC0> 返回一个可迭代对象
    126 print(type(result)) # <class 'callable_iterator'>
    127 
    128 
    129 ''' 匹配替换 '''
    130 
    131 s = '''bottle
    bag
    big
    apple'''
    132 
    133 print('------------------匹配替换------------------')
    134 # 替换方法:
    135 regex = re.compile('bwg')
    136 result = regex.sub('magedu', s)
    137 print(result)# 打印如下
    138 '''
    139 bottle
    140 magedu
    141 magedu
    142 apple
    143 '''
    144 result = regex.sub('magedu', s, 1) # 指定替换次数
    145 print(result)
    146 
    147 '''subn'''
    148 regex = re.compile('s+')
    149 result = regex.subn('	', s)
    150 print(result) # ('bottle	bag	big	apple', 3) 替换了的次数,替换后的序列
    151 
    152 
    153 
    154 ''' 分割方法 '''
    155 '''
    156 字符串 的 分割split,太难用,不能给指定多个字符进行分割
    157 '''
    158 print('------re.spilt------------')
    159 
    160 s = '''01 bottle
    161 02 bag
    162 03      big1
    163 100         able'''
    164 
    165 ''' 每行单词提取出来 '''
    166 # 是否需要保留 big1 后面的1
    167 regex = re.compile('s+d+s+')
    168 result = regex.split(s)
    169 print(type(result))
    170 print(result)
    171 
    172 regex = re.compile('[sd]+')
    173 result = regex.split(' ' + s)
    174 print(result)
    175 
    176 
    177 '''  分组  '''
    178 '''
    179 使用小括号的pattern 捕获的数据被放到了组group中
    180 match,search函数可以返回match对象,findall返回字符串,finditer返回一个个match对象
    181 如果pattern中使用了分组,如果有匹配的结果,会在match对象中
    182     1、使用group(n)方式返回对应分组,1到N 是对应的分组,0 返回 整个匹配的字符串
    183     2、如果使用了命名分组,可以使用group('name')的方式取分组
    184     4、使用groupdict()返回所有命名的分组
    185 '''
    186 
    187 s = '''bottle
    bag
    big
    apple'''
    188 print('------- 分组 -----------')
    189 # 分组
    190 regex = re.compile('(bw+)')
    191 result = regex.match(s)
    192 print(type(result)) # <class 're.Match'>
    193 print(1, 'match', result.groups()) # 1 match ('bottle',)
    194 
    195 
    196 regex = re.compile('(b)(w+)')
    197 result = regex.match(s)
    198 print(result) # <re.Match object; span=(0, 6), match='bottle'>
    199 print(type(result)) # <class 're.Match'>
    200 print(1, 'match', result.groups()) # 1 match ('b', 'ottle')  两个分组
    201 
    202 
    203 result = regex.search(s, 1)
    204 print(result,result.group())
    205 # <re.Match object; span=(7, 10), match='bag'>      bag
    206 
    207 s = '''bottle
    bag
    big
    apple'''
    208 
    209 # 命名分组
    210 print('----- 命名分组-------- ------------')
    211 regex = re.compile('(bw+)
    (?P<name2>bw+)
    (?P<name3>bw+)' )
    212 result = regex.match(s)
    213 print(result,'+++++')
    214 print(result.groups()) # ('bottle', 'bag', 'big')----
    215 print(result.group(0), '---',result.group(1),'---',result.group(2),'---',result.group(3))
    216 # 0 返回的是匹配到的整个字符串
    217 print(result.group(0).encode()) # b'bottle
    bag
    big' # 为了看到回车,用字节类型
    218 
    219 print(result.group('name2'))
    220 print(result.groupdict()) # {'name2': 'bag', 'name3': 'big'}
    221 
    222 
    223 print('-------------------------------')
    224 s = '''bottle
    bag
    big
    apple'''
    225 # 1
    226 print('-------------1------------------')
    227 regex = re.compile('(bw+)
    (?P<name2>bw+)
    (?P<name3>bw+)',re.I )
    228 result = regex.findall(s)
    229 print(result, type(result))
    230 for x in result:
    231     print(x,type(x), end='----')
    232 print()
    233 # 2
    234 print('-------------2------------------')
    235 regex = re.compile('(bw+)
    (?P<name2>bw+)' ,re.M)
    236 result = regex.findall(s)
    237 print(result)
    238 for x in result:
    239     print(x, end='----')
    240 print()
    241 # 3
    242 print('--------------3-----------------')
    243 regex = re.compile('(bw+)
    ' )
    244 result = regex.findall(s)
    245 print(result)
    246 for x in result:
    247     print(x, end='----')
    248 print()
    249 
    250 # 4
    251 print('--------------4-----------------')
    252 regex = re.compile('(bw+)' )
    253 result = regex.findall(s)
    254 print(result)
    255 for x in result:
    256     print(x, end='----')
    257 print()
    258 
    259 
    260 
    261 regex = re.compile('(?P<head>bw+)')
    262 result = regex.finditer(s)
    263 for i in result:
    264     print(type(i), i, i.group(), i.group('head'))
    测试
     1 ************macth*************
     2 <re.Match object; span=(0, 1), match='b'>
     3 None
     4 None
     5 None
     6 ********macth-compile*********
     7 None
     8 <re.Match object; span=(15, 16), match='a'>
     9 ************search************
    10 <re.Match object; span=(8, 9), match='a'>
    11 <re.Match object; span=(7, 8), match='b'>
    12 1 <re.Match object; span=(0, 1), match='b'>
    13 2 <re.Match object; span=(7, 8), match='b'>
    14 **********fullmatch***********
    15 None
    16 None
    17 None
    18 <re.Match object; span=(7, 10), match='bag'>
    19 ***********findall************
    20 ['b', 'b', 'b', 'b']
    21 re.compile('^b')
    22 ['b']
    23 ['b', 'b']
    24 ['b', 'b', 'b', 'b']
    25 ['b']
    26 ['b']
    27 ***********finditer***********
    28 1 <re.Match object; span=(0, 1), match='b'>
    29 1 <re.Match object; span=(7, 8), match='b'>
    30 1 <re.Match object; span=(11, 12), match='b'>
    31 <callable_iterator object at 0x0000000001DC2160>
    32 <class 'callable_iterator'>
    33 ------------------匹配替换------------------
    34 bottle
    35 magedu
    36 magedu
    37 apple
    38 bottle
    39 magedu
    40 big
    41 apple
    42 ('bottle	bag	big	apple', 3)
    43 ------re.spilt------------
    44 <class 'list'>
    45 ['01 bottle', 'bag', 'big1', 'able']
    46 ['', 'bottle', 'bag', 'big', 'able']
    47 ------- 分组 -----------
    48 <class 're.Match'>
    49 1 match ('bottle',)
    50 <re.Match object; span=(0, 6), match='bottle'>
    51 <class 're.Match'>
    52 1 match ('b', 'ottle')
    53 <re.Match object; span=(7, 10), match='bag'> bag
    54 ----- 命名分组-------- ------------
    55 <re.Match object; span=(0, 14), match='bottle
    bag
    big'> +++++
    56 ('bottle', 'bag', 'big')
    57 bottle
    58 bag
    59 big --- bottle --- bag --- big
    60 b'bottle
    bag
    big'
    61 bag
    62 {'name2': 'bag', 'name3': 'big'}
    63 -------------------------------
    64 -------------1------------------
    65 [('bottle', 'bag', 'big')] <class 'list'>
    66 ('bottle', 'bag', 'big') <class 'tuple'>----
    67 -------------2------------------
    68 [('bottle', 'bag')]
    69 ('bottle', 'bag')----
    70 --------------3-----------------
    71 ['bottle', 'bag', 'big']
    72 bottle----bag----big----
    73 --------------4-----------------
    74 ['bottle', 'bag', 'big']
    75 bottle----bag----big----
    76 <class 're.Match'> <re.Match object; span=(0, 6), match='bottle'> bottle bottle
    77 <class 're.Match'> <re.Match object; span=(7, 10), match='bag'> bag bag
    78 <class 're.Match'> <re.Match object; span=(11, 14), match='big'> big big
    结果

       如果遇到这样的切割问题:

        括号优先级的理解:

      

    为什么要坚持,想一想当初!
  • 相关阅读:
    Windows 8.1 序列化与反序列化
    window store app 附件读取
    Window 8.1 计时器功能及图片切换
    c#多层嵌套Json
    isNotNull与isNotEmpty的区别
    商务用语
    国家气象局三天天气WebService接口
    WebServise
    EF架构基础代码
    接口定义
  • 原文地址:https://www.cnblogs.com/JerryZao/p/9609912.html
Copyright © 2011-2022 走看看