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

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

直接先上例子

>>> 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

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

时间: 2024-07-30 10:10:23

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

Python的功能模块[1] -&gt; struct -&gt; struct 在网络编程中的使用

struct模块 / struct Module 在网络编程中,利用 socket 进行通信时,常常会用到 struct 模块,在网络通信中,大多数传递的数据以二进制流(binary data)存在.传递字符串时无需过多担心,但传递 int,char 之类的基本数据时,就需要一种机制将某些特定的结构体类型打包成二进制流的字符串,然后在进行网络传输,而接收端也可以通过某种机制进行解包还原出原始数据.struct 模块便提供了这种机制,该模块主要作用就是对 python 基本类型值与用 python

Python之常用模块(六)re模块与logging模块和包

5.10 re模块 re(正则)简介:正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则. re元字符 元字符 匹配内容 \w 匹配字母(包含中文)或数字或下划线 \W 匹配非字母(包含中文)或数字或下划线 \s 匹配任意的空白符 \S 匹配任意非空白符 \d 匹配数字 \D 匹配非数字 \A 从字符串开头匹配 \n 匹配一个换行符 \t 匹配一个制表符 ^ 匹配字符串的开始 $ 匹配字符串的结尾 . 匹配任意字符,除了

Python基础16模块-re模块

1.正则表达式 #^表示在字符串开头匹配,$表示在字符串结尾匹配 #*匹配0到无穷多个 #+匹配1到无穷多个 #?匹配0或者1个 #{}定义匹配个数{0,}==*,{1,}==+,{0,1}==?,{6}=={1,6} #上面的元字符一般都是贪婪匹配,在后面加上?变成惰性匹配 #[]匹配括号里的字符,只匹配一次,^表示不包含,-表示范围,\表示转义字符,其他在中括号里都无特殊意义 #\d 匹配任何十进制的数 #\D 匹配任何非数字字符 #\s 匹配任何空白字符 #\S 匹配任何非空白字符 #\w

python基础之模块二

六 logging模块 6.1 函数式简单配置 import logging #导入模块 logging.debug('debug message') #调试消息 logging.debug('info message') #导入消息 logging.debug('warning message') #警告消息 logging.error('error message') #错误消息 logging.critical('critical message') #严重信息 默认情况下python的l

Python基础-----logging模块

#!/usr/bin/env python#-*- coding:utf-8 -*- ########################################################################################################################################################灵活配置日志级别,日志格式,输出位置#####################################

python安装markupsafe模块时卡死的解决办法

起因: 升级OS X从10.8到10.9,会发现在安装python的markupsafe模块时一直卡住. 当时的机器环境是: OSX 10.9, XCode 4.6.2, Python 2.7.6, Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn) 界面一直停留在下面的情况 mbp:MarkupSafe-0.23 $ python setup.py install running install running bdis

Linux升级Python提示Tkinter模块找不到解决

一.安装tkinter 在Linux中python默认是不安装Tkinter模块, [[email protected]193 ~]# python Python 2.6.6 (r266:84292, Feb 22 2013, 00:00:18) [GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2 Type "help", "copyright", "credits" or "license

windows 下 python 在安装模块的时候出现”unable to find vcvarsall.bat“如何解决?

最近打算用python,写一个链接linux,执行命令并获取的数据的小工具. 在安装SSH模块时,出现错误了,“unable to find vcvarsall.bat”,在网上搜索到了一个解决方案,参考地址:http://www.crifan.com/python_mmseg_error_unable_to_find_vcvarsall_bat/ Python 2.7 会搜索 Visual Studio 2008.如果你电脑上没有这个版本的话,比如只有:1.Visual Studio 2010

解决python中selen模块中&#39;list&#39; object has no attribute &#39;send_keys&#39;报错

程序在执行如下代码的时候报错'list' object has no attribute 'send_keys' 解决: 把find_elements_by_id方法改成find_element_by_id 参考: https://stackoverflow.com/questions/29957373/selenium-python-send-key-error-list-object-has-no-attribute 解决python中selen模块中'list' object has no