如何构建一个正则表达式来捕获由单个空格分隔的单词?

Posted

技术标签:

【中文标题】如何构建一个正则表达式来捕获由单个空格分隔的单词?【英文标题】:How can I build a regular expression that captures words separated by single spaces? 【发布时间】:2016-08-13 10:14:48 【问题描述】:

我想构建一个正则表达式来捕获

Fee fie foe foo!

但是当有多个空格时:

Fee fie  foe foo!

仅捕获“Fee fie”

我的正则表达式看起来像这样:

words_re = re.compile(r"\w[-\w .,!]*")

您可以看到捕获以字母数字开头的任何序列,然后是字母数字、空格和一些选定的标点符号的任意组合。我只是想一次将其限制为一个空间。

或者,返回分隔空白跨度的 string.split() 变体也可以为我做。

我得到的最接近的是:

words_re = re.compile(r"\w[-\w.,!]*|\s+")
l = words_re.findall(s)

但我需要在返回的列表中搜索仅包含单空格分隔符的子列表,然后从中重建字符串。

我的一个想法是从上面的表达式中取出结果,然后用string.split(" ") 进一步拆分它,将它分成两个空格分隔的子组,但是三个空格的情况呢,等等?

【问题讨论】:

所以你想丢弃两个空格子字符串之后的任何东西,如果存在的话? 这是一个很好的方法\S+(?:\s\S+)+ 这是在两个或多个空格上拆分的逆操作。我不会想太多。 @nephtes,我会在下一次循环中的双空格后回来处理部分。 Meta:感谢大家给我指点regex101.com——我不知道有这么棒的资源存在。 【参考方案1】:

这会起作用

^(\w+(?:\s[-.!\w]+)*(?:[-.!\w]*$))

Regex Demo

如果你只想匹配一个空格字符串,你可以使用(这只会从开始匹配。如果你想捕获所有可能性,你可以删除锚点)

^(\w[-.!\w]*(?:\s[-.!\w]+)*)

Regex Demo

【讨论】:

第二个似乎做了我想要的。让我在我的应用中测试它…… @EdwardFalk 希望你不要为最后一句话后面的空格而烦恼,否则我可以修改它..没关系,因为你已经抓住了任何需要的东西 好的,稍微修改一下你的,这就是我决定的:\w[-.!\w]+(?:\s[-.!\w]+)*——它很好地解决了我的问题。关键是我忘记了(?:…),它允许在不定义捕获组的情况下使用括号。 @EdwardFalk 我的正则表达式需要稍作更正。它与你修改的相似。你的第一个单词至少需要两个字母 @EdwardFalk 然后两者,您和我的正则表达式将相同..)【参考方案2】:

试一试

^((?:\w+(?: |[^ ]$))+)

你可以看到它live here

我们首先匹配一个词与\w 然后我们允许它后跟一个空格,或者如果到达字符串(?: |[^ ]$) 的末尾,则可以是除空格以外的任何内容 我们重复匹配每个单词后跟一个空格或直到到达结尾+

【讨论】:

【参考方案3】:

不使用正则表达式的替代解决方案:

import itertools

def up_to_double_space(str):
    return " ".join(itertools.takewhile(lambda word: word, str.split(" ")))

up_to_double_space("Fee fie foe foo!")
# 'Fee fie foe foo!'
up_to_double_space("Fee fie  foe foo!")
# 'Fee fie'

【讨论】:

哦,这很聪明。【参考方案4】:

这更像是一个评论而不是一个解决方案,但我缺乏对此的代表,但有一个拆分解决方案可能对你有用。 split 接受一个参数,并将在此基础上进行拆分。如果您使用空格作为参数,则会在列表中插入一个空字符串(从两个空格之间)。缺点是其他空格(制表符等)不会导致拆分。

In [15]: x = 'fie fie  foo fum'

In [16]: x.split(' ')
Out[16]: ['fie', 'fie', '', 'foo', 'fum']

In [17]: x.split(' ')[:x.split(' ').index('')]
Out[17]: ['fie', 'fie']

标点符号也没有选择性,这可能是个问题。

总的来说,我认为正则表达式是正确的答案,但如果它可以满足您的所有需求,那么使用和维护起来会简单得多。

【讨论】:

哦嗬。我假设split(x) 会在任何x 序列上分裂,就像split() 会在任何空白序列上分裂一样。我没有意识到 split(x) 在 x 的 single 实例上分裂。这改变了事情。谢谢。

以上是关于如何构建一个正则表达式来捕获由单个空格分隔的单词?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用正则表达式提取骆驼大小写字符串的所有单词?

Python 正则表达式将空格分隔的单词分隔成一个列表

如何使正则表达式在每个单词之间强制使用逗号?

《python核心编程》——正则表达式学习笔记(课后练习)

正则表达式 - 查找所有空格并忽略多行字符串中的连字符分隔的单词

python正则表达式匹配一个空格分隔的所有单词对