【问题标题】: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——我不知道有这么棒的资源存在。

标签: python regex


【解决方案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 实例上分裂。这改变了事情。谢谢。
    猜你喜欢
    • 2016-09-15
    • 1970-01-01
    • 2015-09-10
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-20
    相关资源
    最近更新 更多