码迷,mamicode.com
首页 > 编程语言 > 详细

如何解决python的re模块group、groups与findall遇见正则表达式中分组"()"后产生的”眩晕反应“

时间:2018-06-29 18:27:14      阅读:236      评论:0      收藏:0      [点我收藏+]

标签:操作   tuple   形式   出现   TE   att   数字   mat   会展   

 
直接先上例子
>>> re.search((book+), mebookbookme).groups()
(book,)
>>> re.search((book+), mebookbookme).group()
book
>>> re.search((book)+, mebookbookme).groups()
(book,)
>>> re.search((book)+, mebookbookme).group()
bookbook
>>> re.findall((book)+, mebookbookme)
[book]
>>> re.findall((book+), mebookbookme)
[book, book]
 
是不是被整晕了?
 
这时,你需要来点理论??回下血:
1. 首先要明白:
        search、match与findall在对正则表达式上匹配次数的区别:
        search和match(从头开始匹配)都是只匹配字符串中第一次满足正则表达式pattern的内容
        findall则是直接把字符串中所有满足正则表达式pattern的内容匹配出来
2. 其次要弄明白:
        (1)group和groups是两个不同的函数,他们都是搭配search和match后的匹配对象来使用的,因此只会匹配出字符串中第一次满足正则表达式pattern的内容。
        (2)之所以用group和groups是因为在正则表达式中我们会用到括号()来进行单元分组,进行重复内容匹配(小括号后用+号)或指定内容展示(用group(组号)或groups())的操作。
        (3)group和groups的用法区别如下:
 
【m.group()】(这里m是search或者match后生成的对象)
        m.group()可以括号内不填内容,也可以传入一个数字N,即m.group(N)。以下分情况说明:
 
        <不传入N或传入N=0>
m.group() == m.group(0) == 展示匹配到的第一次满足正则表达式pattern的全部内容(所有匹配的字符)
  与括号无关,这个是API规定的,例如‘(book)+‘的正则表达式可以对‘yourbookbook‘匹配展示出‘bookbook‘。
 
        <传入N>0>
        返回第N组括号匹配的字符。(正则表达式内有几个()就有几个分组)
        但m.group(1)、m.group(2)、... 之后的分组都只会展示()匹配到的分组括号里的内容,例如‘(book)+‘的正则表达式用m.group(1)对‘yourbookbook‘匹配也只会展示一个‘book‘(因为只有1组小括号,就只有1个分组)。
 
【m.groups()】
        m.groups() 返回所有括号匹配的字符(正则表达式中有几个括号就会有几个分组的字符串内容展示),以tuple格式作为容器返回。
m.groups() == (m.group(1), m.group(2), ...)
 

什么,还看不懂?
看来??不能停,逐个分析吧:
  1. 首先,分析下正则表达式book+和(book+)
        search对于‘mebookbookme‘字符串,用book+或者(book+)这样的正则表达式匹配到全部内容本来就是‘book‘
        (因为这里+号是仅对k这个字母来匹配重复的,别搞混了)
>>> re.search(book+, mebookbookme)
<_sre.SRE_Match object; span=(2, 6), match=book>
>>> re.search((book+), mebookbookme)
<_sre.SRE_Match object; span=(2, 6), match=book>
            所以不管groups()还是group(),都是‘book‘(一个book)
 
  1. 而search对于(book)+匹配到的全部内容是‘bookbook‘
>>> re.search((book)+, mebookbookme)
<_sre.SRE_Match object; span=(2, 10), match=bookbook>
        使用group()是把正则匹配到的内容都展示,即返回‘bookbook‘
        
>>> re.search((book)+, mebookbookme).group()
bookbook
  使用group(1)是把第一个(当然这里正则只有一个)小括号里匹配的内容展示,即返回‘book‘
  使用groups()是把所有小括里匹配的内容以元组打包了返回(当然这里只有一个小括号),即返回(‘book‘,)
        
>>> re.search((book)+, mebookbookme).groups()
(book,)

 

        使用findall中匹配分组小括号()后带+的例子,和group(1)、groups()展示的类似,就是()后+号匹配到的重复内容是不会展示的,只会展示小括号内的一次内容,说白了就是正则表达式里有几个小括号()就展示几个括号()内的匹配内容。
        
>>> re.findall((book)+, mebookbookme)
[book]
>>> re.findall((book+), mebookbookme)
[book, book]
  1. 第一个findall对(book)+的展示,直接把+号重复的分组合并为一个单元来展示(这个跟search的groups对于(book)+的展示是一样的)
  2. 第二个findall对(book+)的展示,则是把所有分组都展示出来
 再加点??,补充一个例子来说明一下findall:
 
        下面的例子不管字符串中‘ab‘和‘c‘重复几次,都只会展示一个‘ab‘和一个‘c‘,当然之所以返回了两个元组,是因为findall
>>> re.findall((ab)+(c)+, abcc123ababcccc)
[(ab, c), (ab, c)]

 


 

如果我们是要对‘mebookbookme‘匹配出‘bookbook‘,怎么做呢?
 
1. 首先分析的是用match、search还是findall?
        ‘mebookbookme‘中‘bookbook‘不是出现在第一个字母开始的,所以不能用match;
        ‘bookbook‘模式只出现了一次(当然也就是第一次出现‘bookbook‘模式),因此可以用search匹配到;
        当然findall能匹配到所有出现的‘bookbook‘模式,是肯定能用的。
 
2. 具体分析:
(1)使用search
        使用‘(book+)‘的方式来search,匹配到的完整内容就是‘bookbook‘,选用group()或group(0)返回完整内容就可以了。
 
>>> re.search((book)+, mebookbookme).group()
bookbook
>>> re.search((book)+, mebookbookme).group(0)
bookbook

 

        如果要使用group(1)或groups()[0]呢,该用什么正则表达式?
        可以使用‘((?:book)+)‘的非捕获组(非编号组)的方式,即(?:表达式)的形式,这个小括号是没有进入分组编号的。外头之所以还要加个小括号,就是因为我们一旦用了group(1)或groups()[0]这样的方式,必须要有编号为1的小括号分组。
        (PS:当然这个例子这样做太麻烦,肯定不会选用这种方式,只是为了说明用法)
 
>>> re.search(((?:book)+), mebookbookme).group(1)
bookbook
>>> re.search(((?:book)+), mebookbookme).groups()[0]
bookbook

 

(2)使用findall
        使用findall如果搭配小括号分组的话由于同样会只返回小括号里的内容,所以不能用‘(book)+‘的正则表达式,但可以采用非捕获组(非编号组)的方式。
 
>>> re.findall((?:book)+, mebookbookme)
[bookbook]
>>> re.findall((?:book)+, mebookbookme)[0]
bookbook

 

 转载请注明出处:https://www.cnblogs.com/oceanicstar/p/9244783.html

如何解决python的re模块group、groups与findall遇见正则表达式中分组"()"后产生的”眩晕反应“

标签:操作   tuple   形式   出现   TE   att   数字   mat   会展   

原文地址:https://www.cnblogs.com/oceanicstar/p/9244783.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!