python 正则表达式 groups和group有啥区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python 正则表达式 groups和group有啥区别相关的知识,希望对你有一定的参考价值。

为什么
m = re.match("([abc])+", "abc")
print m.groups()
返回的只有('c',) 而不是 abc
而 print m.group() 就能返回整个的字符串
他们到底有什么区别呢 网上的解释我看的不是太明白

group和groups是两个不同的函数。

一般,m.group(N) 返回第N组括号匹配的字符。
而m.group() == m.group(0) == 所有匹配的字符,与括号无关,这个是API规定的。

m.groups() 返回所有括号匹配的字符,以tuple格式。
m.groups() == (m.group(0), m.group(1), ...)

对你给的例子:

m = re.match("([abc])+", "abc")
你的+号在括号外面。括号最多匹配到一个字符,要么是a, 要么是c,这个python引擎匹配的是末尾的c。
而m.group() == m.group(0) 这个返回的是整个匹配的字符串"abc".

关于捕获型括号在正则表达式里的用法,参见相关文档。追问

如果 m.groups() == (m.group(0), m.group(1), ...) 那么groups是不是应该输出(abc,a,b,c) 而且因为+不是可以匹配一个或者多个么? 所以是不是应该有 m.group(0), m.group(1),m.group(2), m.group(3)三个数据

追答

m.group(2), m.group(3) 的意思是返回第2/3组括号匹配的字符串。
你看看你的表达式里面有几组括号?只有一组。所以在这个例子里面,这两个应该都是返回错误。

追问

那我可以把正则表达式改为:
m = re.match("([abc])+\1", "abc")
print m.group()
么, \1是否是输出第一组信息 我试了一下 好像不行 \1为什么不对, 为什么呢?
而且 既然m.group(1) 既然为c, 那么, groups是不是应该为(abc, c)呢?

追答

>> 既然m.group(1) 既然为c, 那么, groups是不是应该为(abc, c)呢?

对不起。解释groups()的时候错了。应该是:
m.groups() == (m.group(1), m.group(2), ...)
不包括group(0)。可以阅读官方文档:
http://docs.python.org/2/library/re.html

就我个人而言,\N除了查找替换之外很少用。你可以说说你希望得到什么结果,我帮你写表达式。尽量避免使用\N。

追问

多谢 主要我是不了解group和groups是怎么个操作方法 譬如如下的:
p = re.compile(r'[ ]+(\w+)+[ ]+')
print p.search('Paris in the the spring spring ').group()
我觉得 group(1)是否应该返回的是spring, 如果按照您说的那样子的话,可是为什么返回的是in呢.
同理: 我找成对的字符串 p = re.compile(r'[ ]+(\w+)+[ ]+\1') 为什么返回的是 the 而不是spring, 它不是最后一个放到group呢? 再次感谢

追答

p = re.compile(r'[ ]+(\w+)+[ ]+\1')
单个字符不需要[],可以简化为
p = re.compile(r' +(\w+)+ +\1')

(\w+)+这种写法效率很低,而且容易引起误会。表面上它匹配的是任意多个word(1个或更多),其实整体匹配的内容和一个word没区别,只是括号匹配的部分变得不清楚。
整体匹配上:(\w+)+ == \w+
括号匹配多少视engine而定,一般的语言实现应该都是(\w+)+ == (\w+)

如果要返回紧挨着的(空格分开)重复字串,我会这么做:
#!/usr/bin/env python
# coding=utf-8

import itertools

long_text = 'Paris in the the spring spring '

words = long_text.split()

repeats = [x for x, y in itertools.izip(words,
itertools.islice(words, 1, None))
if x == y]

==========================================
p = re.compile(r'[ ]+(\w+)+[ ]+')
等价于
p = re.compile(r' +(\w+) +')

这个匹配:N个空格,1个word,N个空格(N>=1)。
print p.search('Paris in the the spring spring ').group()
整个字符串里面,第一个能匹配到的是" in ",最后一个能匹配到的是" spring "。python的re module是找到一个匹配就停下来返回结果了,所以(\w+)就捕获到了"in",你也可以输出group(0),应该是匹配" in "。
其实别的语言的正则表达式引擎可以返回不同的结果。不见得一定返回第一个匹配项。

==========================================
正则表达式只是一个工具,而且不复杂。学习的时候可以从简单开始,不要人为把它复杂化。
尽量从实际需求出发设计正则表达式,不要为了使用表达式的某些功能设计表达式。

==========================================
如果要用正则表达式找重复单词,可以这么做:
import re
for mo in re.finditer(r'(\w+) +\1', long_text):
print mo.group(0)

参考技术A

group和groups是两个不同的函数。

一般,m.group(N) 返回第N组括号匹配的字符。
而m.group() == m.group(0) == 所有匹配的字符,与括号无关,这个是API规定的。

m.groups() 返回所有括号匹配的字符,以tuple格式。
m.groups() == (m.group(0), m.group(1), ...)

正则表达式中,group()用来提取分组截获的字符串,()用来分组。

组是通过 "(" 和 ")" 元字符来标识的。 "(" 和 ")" 有很多在数学表达式中相同的意思;它们一起把在它们里面的表达式组成一组。举个例子,你可以用重复限制符,象 *, +, ?, 和 m,n,来重复组里的内容,比如说(ab)* 将匹配零或更多个重复的 "ab"。

如果不引入括号,整个个表达式作为一个组,是group(0)



对于题目中的例子:

m = re.match("([abc])+", "abc")
+号在括号外面。括号最多匹配到一个字符,要么是a, 要么是c,这个python引擎匹配的是末尾的c。
而m.group() == m.group(0) 这个返回的是整个匹配的字符串"abc".

参考技术B 一、解释:  match()函数只检测RE是不是在string的开始位置匹配  search()会扫描整个string查找匹配,会扫描整个字符串并返回第一个成功的匹配  也就是说match()只有在0位置匹配成功的话才有返回,如果不是开始位置匹配成功的话,match()就返回none二、例子:  match():   print(re.match(‘super’, ‘superstition’).span())会返回(0, 5)   print(re.match(‘super’, ‘insuperable’))则返回None  search():   print(re.search(‘super’, ‘superstition’).span())返回(0, 5)   print(re.search(‘super’, ‘insuperable’).span())返回(2, 7) 参考技术C 结合所有回复,先上个我的例子作答:
import re
a = "I am a father, my age is 35. I like reading."
b = re.match('(I am).*?(\d+)', a, )
c = re.match('[Ii] am', a)
print(b.group())
print(b.group(0))
print(b.group(1))
print(b.group(2))
print(b.group(0,1,2))
print(b.groups())
#以下是对应的输出:
I am a father, my age is 35

I am a father, my age is 35 #可以看出group()默认参数是0,等于group(0),\
也即要匹配的字符串
I am #第1个括号的匹配

35 #第2个括号的匹配,表达式中有多少个括号,\
参数就最大是括号数
('I am a father, my age is 35', 'I am', '35')

('I am', '35') #groups()==group(1,2),是不包含group(0)的

楼主对正则的[]不理解,[abc]内只能匹配a,或b,或c。如果要匹配'abc',只能写成:
a = 'babccabc'

b = re.match('abc', a)

c = re.match(('abc'), a)

d = re.search('abc', a)

e = re.search(('abc'), a)

print(b) #match()只能匹配字符串开始处,匹配不上返回None

print(c) #可以看出一个匹配内容,可以有无小括号

print(d.group(0))

print(e.group())
#以下为输出
None
None
abc
abc

经多次测试,楼主的表达式含‘+’,会导致往后匹配,相当于贪婪模式,但是最后的数据确是取最后一位字母,而不是第一位,这点目前还不能给你个合理的解释
参考技术D m.groups返回一个包含所有字符的元组,而m.group返回一个包含那些组所对应值的元组

Python正则表达式

match(pattern,string,flag=0)    匹配成功就返回匹配对象,匹配失败就返回None。

search(pattern,string,flag=0)   在字符串中搜索第一次出现的正则表达式模式,如果匹配成功,就返回匹配对象,匹配失败就返回None。

 

匹配对象需要调用group() 或 groups() 方法。

group()要么返回整个匹配对象,要么返回特定的子组。

groups()返回一个包含唯一或者全部子组的元组。如果没走子组要求,将返回空元组。

 

findall(pattern,string[,flags])  查找字符串中所有出现的正则表达式模式,并返回一个匹配列表。

finditer(pattern,string[,flags])  与findall()函数相同,但返回的不是一个列表,而是一个迭代器。对于每一次匹配,迭代器都返回一个匹配对象。

import re

s = ‘this and that‘
m = re.findall(r‘(th\w+) and (th\w+)‘,s,re.I)
print 1,m

m = re.finditer(r‘(th\w+) and (th\w+)‘,s,re.I)
print 2,m

for g in re.finditer(r‘(th\w+) and (th\w+)‘,s,re.I):
print 3,g.group()
print 4,g.group(1)
print 5,g.group(2)
print 6,g.groups()

m = re.findall(r‘(th\w+)‘,s,re.I)
print 7,m

g = re.finditer(r‘(th\w+)‘,s,re.I)
m = g.next()
print 8,m.groups()
print 9,m.group(1)
m = g.next()
print 10,m.groups()
print 11,m.group(1)

print 12,[g.group() for g in re.finditer(r‘(th\w+)‘,s,re.I)]

运行结果:

1 [(‘this‘, ‘that‘)]
2 <callable-iterator object at 0x02766FD0>
3 this and that
4 this
5 that
6 (‘this‘, ‘that‘)
7 [‘this‘, ‘that‘]
8 (‘this‘,)
9 this
10 (‘that‘,)
11 that
12 [‘this‘, ‘that‘]

 


























以上是关于python 正则表达式 groups和group有啥区别的主要内容,如果未能解决你的问题,请参考以下文章

python 正则表达式 groups和group有啥区别?

python正则表达式02--findall()和search()方法区别,group()方法

python正则中的group()

python --- 正则表达式

Python正则表达式

python常用的正则表达式,持续更新<<