正则基础知识(括号的使用)

一、分组功能
   括号作用于几个字符的话,就说明这几个字符是一个整体,比如(ab)+就匹配ab作为一个整体出现的情况
   例如:
   print re.search(r"^ab+$", "abb") != None   # =>True
   print re.search(r"^ab+$", "abab") != None   # =>False
   print re.search(r"^(ab)+$", "abb") != None  # =>False
   print re.search(r"^(ab)+$", "abab") != None # =>True
   一种常见的用法就是要匹配m或者n个字符的时候,就可以用分组来实现:\d{13,16}表示13-16个数字,如果要表示13或者16个数字的时候就可以用 \d{13}(\d{3})?

二、多选结构
   多选结构的形式: "|"
   比如要匹配IP地址一个字段:([0-9]|[0-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])
   注意:^ab|cd$ 表示的是(^ab|cd$),指字符串开头的ab或者字符串结尾的cd,要表示只包含ab或者cd的字符串需要用^(ab|cd)$

三、引用分组
   使用括号之后,正则表达式会保存每个分组真正匹配的文本,等到匹配完之后,通过group(num)之类的方法引用分组在匹配时获取的内容。
   例如:表示日期字符串:2010-12-22,匹配表达式为(\d{4})-(\d{2})-(\d{2})
   print re.search(r"(\d{4})-(\d{2})-(\d{2})", "2012-12-22").group(1) # =>2012
   print re.search(r"(\d{4})-(\d{2})-(\d{2})", "2012-12-22").group(2) # =>12
   print re.search(r"(\d{4})-(\d{2})-(\d{2})", "2012-12-22").group(1) # =>22
   print re.search(r"(\d{4})-(\d{2})-(\d{2})", "2012-12-22").group(0)
   # =>2012-12-22 (编号为0的分组对应整个表达式匹配的文本)

   对于嵌套的括号,分组的编号是根据开括号出现的顺序来计数的, 例如:
   (((\d{4})-(\d{2}))-(\d{2})),编号为0和编号为1的分组对应2012-12-22,编号为2的分组对应2012-12,编号为3的分组对应2012,编号为4的分组对应12,编号为5的分组对应22

  python语言中进行正则表达式的替换方法是re.sub(pattern, replacement, string),其中pattern是用来匹配被替换文本的表达式,replacement是要替换成的文本,string是要进行替换操作的字符串,比如re.sub(r"[a-z]", " ", string)就是将string中的小写字母替换成空格,例如:
  print re.sub(r"[a-z]", " ", "1a2b3c") # =>1 2 3

  在replacement中也可以引用分组,形式是\num,num是对应分组的编号
  例如:
  print re.sub(r"(\d{4})-(\d{2})-(\d{2})", r"\2/\3/\1", "2012-12-22")
  # =>12/22/2010   (其中r"\2/\3/\1" 也可用用"\\2/\\3/\\1"替换)
  值得注意的是此处不能用\0,因为\0已经被用作八进制形式表示的字符,如果需要取相同的值得话,可以先用括号把整个表达式加上一对括号,之后用\1来引用

四、反向引用
  如果希望检查某个单词是否包含重叠出现的字母,就需要用到反向引用,反向引用就是在正则表达式内部引用之前捕获分组匹配的文本,例如([a-z])\1匹配连续重叠字母的表达式
  例如:
  print re.search(r"^([a-z])\1\1$", "aa") != None   # =>True

  pairedTagRegex = r"<([^>]+)>[\s\S]*?</\1>"
  print re.search(pairedTagRegex, "<bold>text</bold>") != None # =>True

  pairedTagRegex = r"<([a-zA-Z0-9]+)(\s[^>]+)?>[\s\S]*?</\1>"
  print re.search(pairedTagRegex, "<span class=\"class1\">text</span>") != None
  # =>True

注意:python中\10表示第10个编号的分组,所以如果要表示第一个编号的分组加上0的话就可以使用\g<1>0这种方式,这样可以避免二义性

五、命名分组
  又有用数字编号来表示分组不够直观,并且括号多了之后容易混淆,所以一些语言和工具又提供了命名分组,在Python中用(?P<name>)来分组,再用group(name)来获得对应分组匹配的文本
  例如:
  namedRegex = r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})"
  result = re.search(namedRegex, "2012-12-22")
  print result.group("year")  # =>2012
  print result.group("month")  # =>12
  print result.group("day")    # =>22
  print result.group(1)  # =>2012

六、非捕获分组
  用非捕获分组修饰的表达式,在引用分组的时候会略过,非捕获表达式的形式为:(?:\d{4})

七、括号的转义
  ()|这三个符号在转义的时候都必须转义,不能只转义一个比如"^\(a\|b\)$"

你可能感兴趣的:(正则基础)