代码没有导入

正则表达式(RegularExpression, re)

  • 是一个计算机科学的概念
  • 用于使用单个字符串来描述,匹配一系列匹配某个句法规则的字符串
  • 常用来检索,替换某些模式的文本
  • 正则表达的写法

  • .(点号): 匹配任意一个字符,出了 \n
  • []:匹配中括号中列举的字符,例如[LY]
  • \d: 表示任意一个数字, 0-9
  • \D: 表示非数字,即不是数字就可以
  • \s:匹配空白,即空格,tab键
  • \S:除了空白意外的字符
  • \w:单词字符,即a-z, A-Z, 0-9, _
  • \W:非单词字符
  • *: 表示前面内容重复零次或者多次
  • +:前面内容重复至少一次
  • ?:前面出现的内容零次或者一次
  • {m,n}:允许前面内容出现最少m次,最多n次
  • ^:匹配字符串的开始
  • $:匹配字符串的结尾
  • \b:匹配单词的边界
  • ():对正则表达式内容进行分组, 从第一个括号开始,编号逐渐增大

      验证一个数字: ^\d$
      必须有一个数字,最少一位:^\d+$
      只能出现数字,且位数为5-10位: ^\d{5,10}$
      注册者输入年龄,要求16岁以上,99岁以下: ^[16-99]$
      只能输入英文字符和数字: ^[A-Za-z0-9]$
      验证qq号码: [0-9]{5,12}
    
  • \A: 只匹配字符串开头, \Aabcd, 则abcd
  • \Z: 仅匹配字符串末尾, abcd\Z, abcd
  • : 左右任意一个
  • (?P...): 分组,除了原来的编号再制定一个别名, (?P12345){2}, 1234512345
  • (?P=name): 引用分组,

re 模块

  • re.match(re_exp):从开始查看是否能跟定义的正则相匹配
  • result.group:如果匹配数据成功,可以使用group来提取数据
  • 案例01

re中原生字符串问题

  • 字符串中会包含转义字符
  • 在re中,转义字符会带来一些麻烦,能不能尽量减少转义字符的出现
  • 在字符串前使用r字符,表示后面字符串是原始字符串,不需要转移,例如 r’c:\wk\readme.txt’
  • 案例01-fun_4

    正则的分组表示

  • :匹配左右任意一个表达式
  • (ab):将括号中字符作为一个分组
  • \num:引用分组num匹配到的字符串
  • (?P):分组起一个别名, 其中P是大写
  • (?P=num):引用别名为name分组匹配到的字符串
  • 案例01中 fun_5函数

re 模块的一般使用步骤如下:

  1. 使用 compile() 函数将正则表达式的字符串形式编译为一个 Pattern 对象
  2. 通过 Pattern 对象提供的一系列方法对文本进行匹配查找,获得匹配结果,一个 Match 对象。
  3. 最后使用 Match 对象提供的属性和方法获得信息,根据需要进行其他的操作

re常用函数

  • group([group1, …]) 方法用于获得一个或多个分组匹配的字符串,当要获得整个匹配的子串时,可 直接使用 group() 或 group(0);
  • start([group]) 方法用于获取分组匹配的子串在整个字符串中的起始位置(子串第一个字符的索 引),参数默认值为 0;
  • end([group]) 方法用于获取分组匹配的子串在整个字符串中的结束位置(子串最后一个字符的索引 +1),参数默认值为 0;
  • span([group]) 方法返回 (start(group), end(group))。

正则的其他用法

  • 案例01, fun_6
  • search:查找其中一个内容
  • findall:查找所有内容
  • sub:查找替换, 返回替换之后的内容,原来倍替换的内容不变

匹配代码

    import re

    p = re.compile(r'\d+') 

    m = p.match("one12twothree34four")

    print(m)

    import re
     

    m = p.match("one12twothree34four", 3, 10)

    print(m)

    print(m[0])

    m.start(0) # 参数是组号
    m.end(0)

    #第二个例子
    import re

    p = re.compile(r'([a-z]+) ([a-z]+)',re.I) # re.I表示忽略大小写, 两个中间有空格

    m = p.match('I really love wangxiaojing ')

    print(m)

    print(m.group(0))

    m.start(0)

    m.span(0)

    m.group(1)

    m.group(2)

    m.group(0) # 整个匹配子串

    m.groups() # 全部的打印出来

查找代码

  • search(str[, pos[, endpos]])
  • findall
  • finditer

     import re
     p = re.compile(r'\d+')
    
     m = p.search('one12twothree34four')
    
     m.group()
    
     p = re.compile('\d+')
    
     m = p.search('hello 123456 7890')
    
     print(m.group())
       
       
     #findall
     rst = p.findall("hello 12345 67890")
     print(rst)
    

sub替换

  • sub(rep1, str[,count])

      import re
         
      p = re.compile(r'(\w+) (\w+)') #\w是字符
      s = "hello 123 and hello 456"
    
      rst = p.sub(r'hello world', s)
      print(rst)
    
      rst = p.sub(r'\2 \1', s)
      print(rst)
    
      def func(m):
          return 'gaga' + m.group(2)
    
      rst = p.sub(func, s)
      print(rst)
    
      rst = p.sub(func, s,1)
      print(rst)
    

匹配中文

  • 中文主要表示范围是 [u4e00-u9fa5], 不包括拳脚标点

      import re
    
      title = u'你好 世界, hello moto'
    
      p = re.compile(ur"[\u4e00-\u9fa5]+") # ur有可能冲突
    
      rst = p.findall(title)
    
      print(rst)
    

贪婪和非贪婪

  • 尽可能多的匹配,(*)
  • 非贪婪, (?)
  • 默认贪婪

      import re
    
      title = u'<div>name</div><div>age</div>'
    
    
      p1 = re.compile(r"<div>.*</div>")  
      p2 = re.compile(r"<div>.*?</div>")  
    
      m1 = p1.search(title)
      print(m1.group())
    
      m2 = p2.search(title)
      print(m2.group())