2. 正则中特殊符号所代表的含义与例子

  1. .

    点字符默认情况下表示任意字符,但是不包括

    可以通过flag标志来声明.点匹配包括

    • 不包括换行
      	import re
      	ret = re.match(".*","hello\
      hello")
      	print(ret.group())
      
    • 包括换行
      	import re
      	ret = re.match(".*","hello\
      hello",re.DOTALL)
      	print(ret.group())
      

    re.DOTALL表示匹配所以字符。

  2. ^ 行首

    ^表示这一行必须是以某种规则开始。

    ^re.MULTILINE模式中,表示按照 为分界线,进行一行一行的方式解析。

    • 普通行首
      	import re
      	ret = re.match("^hel.*","hello\
      hello")
      	print(ret.group())
      
    • 多行匹配
      	import re
      	ret = re.match("^hel.*
      ^hel.*","hello\
      hello",re.MULTILINE)
      	print(ret.group())
      
      注意:这里有两个^,以及添加了re.MULTILINE
  3. $ 行末尾

    筛选以某种规则结尾的字符串。

    • 非多行
      	import re
      	ret = re.findall(".+$","hello world\
      hello")
      	print(ret)
      
    • 多行
      	import re
      	ret = re.findall(".+$","hello world\
      hello",re.MULTILINE)
      	print(ret)
      
  4. * 贪婪匹配

    尽量多的匹配,*等价于{0,INFINITY} INFINITY表示无穷大,后面也一样。

    	import re
    	ret = re.findall(".*","hello world\
    hello")
    	print(ret)
    
  5. + 多个

    尽量多的匹配,+等价于{1,INFINITY}

    	import re
    	ret = re.findall(".+","hello world\
    hello")
    	print(ret)
    
  6. ? 0或1

    尽量多的匹配一个或0个,.?等价于{0,1}

    	import re
    	ret = re.findall(".?","hello world\
    hello")
    	print(ret)
    
  7. *? +? ??非贪婪匹配,尽量少的匹配

    与上面三个相反。

    • 贪婪模式
      	import re
      	ret = re.findall("<.*>","<html></html>")
      	print(ret)
      
    • 非贪婪模式
      	import re
      	ret = re.findall("<.*?>","<html></html>")
      	print(ret)
      
  8. {m} 严格匹配m个重复字符

    	import re
    	ret = re.findall("a{1}","a<html>a</html>")
    	print(ret)
    
  9. {m,n} 至少m个,最多n个。

    贪婪匹配,尽可能多的匹配。

    	import re
    	ret = re.findall("a{1,5}","aaaaa<html>a</html>")
    	print(ret)
    
  10. {m,n}?非贪婪模式匹配

    import re
    ret = re.findall("a{1,5}?","aaaaa<html>a</html>")
    print(ret)
    
  11. []集合中任选一个

    []只代表一个字符,即,括号之间的所有字符中的任意一个可以满足.

    并且这里面的所有的字符都失去它原来的特殊意义。

    几种声明方式,一一列举,范围列举,集合,取反

    • 一一列举
      	import re
      	ret = re.findall("[a<]+","aaaaa<html>a</html>")
      	print(ret)
      
    • 范围罗列
      	import re
      	ret = re.findall("[a-z]+","aaaaa<html>a</html>")
      	print(ret)
      
    • 集合
      	import re
      	ret = re.findall("[\w]+","aaaaa<html>a</html>")
      	print(ret)
      
    • 取反
      	import re
      	ret = re.findall("[^\w]+","aaaaa<html>a</html>")
      	print(ret)
      
  12. | 多个表达式,从左往右匹配。

    import re
    ret = re.findall("(a|h)+","aaaaa<html>a</html>")
    print(ret)
    
  13. (...) 创建组

    对于括号里面的表达式,匹配后形成一个组,供后面进行使用。可以通过 umber的形式进行引用。

    如果要是用这个字面值,可以使用( ) [(] [)]

    import re
    ret = re.search("(<html>)a\1","aaaaa<html>a<html>")
    print(ret)
    
  14. (?...) 不创建组

    这种格式的表达式不会创建组,比如(?:hello)

    但是(?P<name>...),这种是创建一个命名组。

  15. (?aiLmsux) 局部按照特殊规则处理

    a 表示按照ASCII的方式匹配
    i ignore case,表示忽略大小写匹配
    L 本地依赖,有的国家的字符排序是 AaBb
    m multi line 多行模式匹配
    s 包含了seperator,即匹配所有,包括换行
    u 按照unicode匹配
    x 去掉注释和空格
  16. (?:...)

    不形成组

    import re
    ret = re.search("(?:<html>)a(</html>)","aaaaa<html>a</html>")
    print(ret.groups())
    
  17. (?aiLmsux-imsx:...)嵌套与局部删除

    如前面用了i,但是我要在满足条件的嵌套组里面不适用i.

    import re
    ret = re.search("(?i:(?:a|b)+(?-i:c+))","aaaaaAAAbbbccC")
    print(ret)
    
  18. (?P<name>...) 创建一个命名组

    name符合python变量定义规则,只能定义一次,首先是一个组,然后再特殊化是一个命了名的组。

    • 在同一个规则中引用
      	import re
      	ret = re.search("(?P<header><html>)a\1","aaaaa<html>a<html>")
      	print(ret,ret.groups())
      
      	import re
      	ret = re.search("(?P<header><html>)a(?P=header)","aaaaa<html>a<html>")
      	print(ret,ret.groups())
      
    • 在结果中访问
      	import re
      	ret = re.search("(?P<header><html>)a(?P=header)","aaaaa<html>a<html>")
      	print(ret,ret.group("header"))
      
    • subn方法中使用
      	import re
      	ret = re.subn("(?P<header><html>)","<\g<header>>","aaaaa<html>a<html>")
      	print(ret)
      
      	import re
      	ret = re.subn("(?P<header><html>)","<\g<1>>","aaaaa<html>a<html>")
      	print(ret)
      
      	import re
      	ret = re.subn("(?P<header><html>)","<\1>","aaaaa<html>a<html>")
      	print(ret)
      
  19. (?P=name)与前面的相呼应。

    见前面的案例

  20. (?#...)

    一个注释,会被忽略

    import re
    ret = re.search("(?P<header><html>)(?# this is a comment)","aaaaa<html>a<html>")
    print(ret,ret.groups())
    
  21. (?=...)

    是否以结尾,不消耗字符

    import re
    ret = re.findall("(?P<header><html>)","aaaaa<html>a<html>")
    print(ret)
    ret = re.findall("(?P<header><html>(?=$))","aaaaa<html>a<html>")
    print(ret)
    
  22. (?!...)

    (?=...)否定版本,不做演示。

  23. (?<=...)

    前缀,而且匹配长度相同,如果是多个匹配规则,长度也必须相同。

    import re
    ret = re.findall("(?<=aa|bb)<html>","aaaaa<html>a<html>")
    print(ret)
    
  24. (?<!...)

    (?<=...)的否定版本。不做演示。

  25. (?(id/name)yes-pattern|no-pattern)

    用于判断组是否存在,是则前面的匹配,否则后面的匹配。经常和?进行搭配

    import re
    ret = re.match("(<html>)(<html>)?(<html>)?a(?(3)</html>|)(?(2)</html>|)(?(1)</html>|$)",
    "<html><html>a</html></html>")
    print(ret)
    

    上面的(<html>)?需要与后面的进行搭配。不然会出错。