Python re.search

15

我有一个包含字符串的变量

string = "123hello456world789"

字符串不包含空格。我想写一个正则表达式,只打印包含(a-z)的单词。我尝试了一个简单的正则表达式

pat = "([a-z]+){1,}"
match = re.search(pat, word, re.DEBUG)

匹配对象仅包含单词Hello,而单词World未匹配。

当使用re.findall()时,我可以得到HelloWorld

我的问题是为什么我们不能用re.search()来做到这一点?

如何使用re.search()实现此功能?


因为 helloworld 不相邻,但这是你的模式正在寻找的。 - Martijn Pieters
1
你为什么想要使用 re.search 来做这件事? - Steinar Lima
在我的原始正则表达式中,我有大约4个组。使用re.findall和组,我无法获得完整的匹配。而使用**re.search(),我可以使用match.group()**完成匹配。 - Krishna M
1
如果您没有提供完整的代码来解决问题,那么您怎么能期望得到答案呢?请使用实际的正则表达式和一些样本输入/输出来提出一个新问题。这是获得正确解决方案的方法,否则您将一无所获。 - Inbar Rose
谢谢你的帮助。我会发布一个新问题。 - Krishna M
抱歉 @InbarRose。我对我的错误深表歉意。我是发布问题的新手。我已经重新发布了清晰地定义所有问题。 - Krishna M
2个回答

16

re.search() 在字符串中找到模式的第一次匹配,文档

扫描字符串查找正则表达式模式产生匹配的位置,并返回相应的MatchObject实例。如果没有任何位置与模式匹配,则返回None;请注意,这与在字符串某个点处找到零长度匹配是不同的。

为了匹配每一个出现的位置,你需要使用re.findall()文档

以字符串列表形式返回所有非重叠的模式匹配项。字符串从左到右进行扫描,并按照发现顺序返回匹配项。如果模式中存在一个或多个组,则返回一个组列表;如果模式有多个组,则这将是一个元组列表。空匹配包括在结果中,除非它们接触到另一个匹配的开头。

示例:

>>> import re
>>> regex = re.compile(r'([a-z]+)', re.I)
>>> # using search we only get the first item.
>>> regex.search("123hello456world789").groups()
('hello',)
>>> # using findall we get every item.
>>> regex.findall("123hello456world789")
['hello', 'world']

更新:

由于您的重复问题请参见此链接讨论),我也在这里添加了我的另一个答案:

>>> import re
>>> regex = re.compile(r'([a-z][a-z-\']+[a-z])')
>>> regex.findall("HELLO W-O-R-L-D") # this has uppercase
[]  # there are no results here, because the string is uppercase
>>> regex.findall("HELLO W-O-R-L-D".lower()) # lets lowercase
['hello', 'w-o-r-l-d'] # now we have results
>>> regex.findall("123hello456world789")
['hello', 'world']

正如你所看到的,你之前提供的第一个样本失败的原因是因为它使用了大写字母,你可以简单地添加re.IGNORECASE标志,尽管你提到匹配应该仅限于小写字母。


1
OP不想出于某些原因使用findall()。这就是问题的重点所在。 - Martijn Pieters
@MartijnPieters OP 还问道:“为什么我们不能使用 re.search() 来实现这个?” - Peter Gibson
@MartijnPieters 好的,没问题(不过这不是我的帖子)。 - Peter Gibson
@Peter:好的,抱歉,我也在忙Inbar的问题,所以我没有读够!:-P - Martijn Pieters

2

@InbarRose的答案展示了re.search为什么能够这样工作,但如果你想要match对象而不仅仅是re.findall的字符串输出,请使用re.finditer

>>> for match in re.finditer(pat, string):
...     print match.groups()
...
('hello',)
('world',)
>>>

或者,如果您想要一个列表

>>> list(re.finditer(pat, string))
[<_sre.SRE_Match object at 0x022DB320>, <_sre.SRE_Match object at 0x022DB660>]

通常不建议将string作为变量名,因为它是一个常用的模块。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接