Python 正则表达式(分组)

正则表达式分组

分组就是用一对圆括号“()”括起来的正则表达式,匹配出的内容就表示一个分组。从正则表达式的左边开始看,看到的第一个左括号“(”表示第一个分组,第二个表示第二个分组,依次类推,须要注意的是,有一个隐含的全局分组(就是0),就是整个正则表达式。
分完组之后,要想得到某个分组的内容,直接使用group(num)和groups()函数去直接提取就行。css

例如:提取代码中的超连接中的文本python

   
   
   
   
   
  • 1
  • 2
  • 3
  • 4
>>> s='<div><a href="https://support.google.com/chrome/?p=ui_hotword_search" target="_blank">更多</a><p>dfsl</p></div>' >>> print re.search(r'<a.*>(.*)</a>',s).group(1) 更多

或者正则表达式

   
   
   
   
   
  • 1
  • 2
  • 3
>>> print re.match(r'.*<a.*>(.*)</a>',s).group(1) 更多

按照上面的分组匹配之后,咱们就能够拿到咱们想拿到的字串,可是若是咱们正则表达式中括号比较多,那咱们在拿咱们想要的字串时,要去挨个数咱们想要的字串时第几个括号,这样会很麻烦,这个时候Python又引入了另外一种分组,那就是命名分组,上面的叫无名分组。chrome

命名分组

命名分组就是给具备默认分组编号的组另外再给一个别名。命名分组的语法格式以下:缓存

   
   
   
   
   
  • 1
(?P<name>正则表达式)#name是一个合法的标识符

如:提取字符串中的ip地址ruby

   
   
   
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
>>> s = "ip='230.192.168.78',version='1.0.0'" >>> re.search(r"ip='(?P<ip>\d+\.\d+\.\d+\.\d+).*", s) >>> res.group('ip')#经过命名分组引用分组 '230.192.168.78'

后向引用

正则表达式中,放在圆括号“()”中的表示是一个组。而后你能够对整个组使用一些正则操做,例如重复操做符。
要注意的是,只有圆括号”()”才能用于造成组。”“用于定义字符集。”{}”用于定义重复操做。
当用”()”定义了一个正则表达式组后,正则引擎则会把被匹配的组按照顺序编号,存入缓存。这样咱们想在后面对已经匹配过的内容进行引用时,就能够用”\数字”的方式或者是经过命名分组进行”(?P=name)“进行引用。\1表示引用第一个分组,\2引用第二个分组,以此类推,\n引用第n个组。而\0则引用整个被匹配的正则表达式自己。这些引用都必须是在正则表达式中才有效,用于匹配一些重复的字符串。
如:markdown

   
   
   
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
#经过命名分组进行后向引用 >>> re.search(r'(?P<name>go)\s+(?P=name)\s+(?P=name)', 'go go go').group('name') 'go' #经过默认分组编号进行后向引用 >>> re.search(r'(go)\s+\1\s+\1', 'go go go').group() 'go go go'

交换字符串的位置函数

   
   
   
   
   
  • 1
  • 2
  • 3
  • 4
>>> s = 'abc.xyz' >>> re.sub(r'(.*)\.(.*)', r'\2.\1', s) 'xyz.abc'

前向确定断言、后向确定断言

前向确定断言的语法:post

   
   
   
   
   
  • 1
(?=pattern)

后向确定断言的语法:ui

   
   
   
   
   
  • 1
(?<=pattern)

须要注意的是,若是在匹配的过程当中,须要同时用到前向确定断言和后向确定断言,那么必须将后向确定断言写在正则语句的前面,前向确定断言写在正则语句的后面,表示后向确定模式以后,前行确定模式以前。
如:获取c语言代码中的注释内容

   
   
   
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
>>> s1='''char *a="hello world"; char b='c'; /* this is comment */ int c=1; /* t his is multiline comment */''' >>> re.findall( r'(?<=/\*).+?(?=\*/)' , s1 ,re.M|re.S) [' this is comment ', ' this is multiline comment ']

(?<=/*)这个是后向确定断言,表示“/*”以后。(?=*/)这个为前向确定断言,表示“*/”以前,这两合并起来就是一个区间了,因此后向确定断言放在前向确定断言前面。

前向否认断言、后向否认断言

前向否认断言语法:

   
   
   
   
   
  • 1
(?!pattern)

后向否认断言语法:

   
   
   
   
   
  • 1
(?<!pattern)

前向否认和后向否认实例:

   
   
   
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
#提取不是.txt结尾的文件 >>> f1 = 'aaa.txt' >>> re.findall(r'.*\..*$(?<!txt$)',f1) [] #提取不以数字开头的文件 >>> re.findall(r'^(?!\d+).*','1txt.txt') [] #提取不以数字开头不以py结尾的文件 >>> re.findall(r'^(?!\d+).+?\..*$(?<!py$)','test.py') [] >>> re.findall(r'^(?!\d+).+?\..*$(?<!py$)','test.txt') ['test.txt']
相关文章
相关标签/搜索