Python 中的正则表达式 findall()

Posted

技术标签:

【中文标题】Python 中的正则表达式 findall()【英文标题】:regular expression findall() in Python 【发布时间】:2013-06-30 13:52:40 【问题描述】:

如果我有这个字符串:

s = "this, that; talk, love, hate; good, bad, all good."

我想提取由 , ; 分隔的项目或。

所以我想要的结果是:

["this", "that", "talk", "love", "hate", "good", "bad", "all good"]

如果我使用这个 Python 正则表达式:

re.findall(r"([a-z]+[,;.])+", s)

我得到了结果:

['this,', 'that;', 'talk,', 'love,', 'hate;', 'good,', 'bad,', 'good.']

这和我想要的很接近,除了最后一项。

奇怪的是,如果我在第一个方括号中包含一个空格,如:

re.findall(r"([a-z ]+[,;.])+", s)

那么我只得到这个结果:

[' all good.']

但是 findall() 应该找到所有结果,不是吗?有人能解释一下这种奇怪的行为吗?

【问题讨论】:

re.split() 可能更适合您的用例。 感谢您的所有回答,我现在可以解决问题了。但最初我对 findall() 感到困惑,我认为它返回 (xyz)+ 的不同实例,但它实际上试图从最后一个位置“重新”找到模式。我想没有办法重新返回与“+”匹配的所有实例? 【参考方案1】:

+(在右引号之前)在括号之外。把它放在里面,这样:

re.findall(r"\s*([a-z ]+)[ ,;.]+", s)

【讨论】:

它将匹配整个括号表达式任意次数>0次 我不太明白他得到的结果..不应该匹配整个字符串吗? ['this,', ' that;', ' talk,', ' love,', ' hate;', ' good,', ' bad,', ' all good.']。它根本无法完成这项工作。 抱歉,我以为那是他想要的。编辑修复。 这个不正确地使用以空格开头的字符串。【参考方案2】:

您的目标是通过分隔符将字符串拆分为标记,因此比使用re.findall() 更好的方法是使用re.split()。在这种情况下,您可以使用

>>> re.split(r"[,;.]\s", s)
['this', 'that', 'talk', 'love', 'hate', 'good', 'bad', 'all good.']

不幸的是,如果您使用[,;.]\s 作为正则表达式,此方法要么将句点放在最后一项的末尾,如果您使用[,;.]\s? 作为正则表达式,则在结果列表的末尾添加一个空字符串正则表达式。但是,我们可以通过删除最后一个字符串来解决这个问题:

>>> re.split(r"[,;.]\s?", s)[:-1]
['this', 'that', 'talk', 'love', 'hate', 'good', 'bad', 'all good']

【讨论】:

【参考方案3】:

您可以使用前瞻:

>>> list(re.findall(r"([a-z][a-z ]+(?=[,;.]))+", s))
['this', 'that', 'talk', 'love', 'hate', 'good', 'bad', 'all good']

但是@murgatroid99推荐的re.split()更好。

【讨论】:

在示例输出中,他希望 "all good" 作为最后一个字符串,而不是 "good",并且您完全删除了“all”这个词【参考方案4】:

你可以使用:

re.findall(r'[\w\s]+', s)

【讨论】:

以上是关于Python 中的正则表达式 findall()的主要内容,如果未能解决你的问题,请参考以下文章

Python 正则表达式 findall 有效,但匹配不 [重复]

是否有 Python 的 re.findall/re.finditer(迭代正则表达式结果)的 Perl 等价物?

python:非正则表达式等价于 re.findall

Python正则表达式之findall疑点

python正则表达式re.findall(r"\b\w+\b", s)中的r是啥意思?

python中的正则表达式