【问题标题】:regex to match the minimum length of each word in a sentence in Python正则表达式匹配Python中句子中每个单词的最小长度
【发布时间】:2018-10-07 06:17:21
【问题描述】:

我想写一个正则表达式,它检查句子中每个单词的长度,如果所有单词的长度至少为 3,则返回True。另外,整个句子只能是小写字母。例如,对于字符串“hello world”,它必须返回真结果,而对于字符串“hi world”,它必须返回假结果。

以下正则表达式无法按预期工作,它给出了True

bool(re.compile('([a-z\s]{3,})+$').match("hi world")))

【问题讨论】:

  • ^([a-z]{3,}\s?)+$
  • 您可以使用re.match(r'\s*[a-z]{3,}(?:\s+[a-z]{3,})*\s*$', s)
  • 你不需要正则表达式 - 用空格分割你的句子并检查所有单词是否至少有 3 个字符长:if all(len(word)>2 for word in sentence.split()) ... 当然,你会有一个如果您必须考虑标点符号,连字符等,则更困难的情况,但即使是正则表达式也不会在没有后处理的情况下完美地做到这一点。
  • @zwer 感谢您的评论。好吧......我可以在没有正则表达式的情况下做到这一点,但我最感兴趣的是正则表达式解决此类问题的功能。

标签: python regex


【解决方案1】:

我认为您不需要正则表达式。你可以这样做:

s = 'this is a sentence of some sort'
words = s.split()
test = [w for w in words if len(w) > 3]
print(len(test) == len(words)) # False

或等效:

s = 'this is a sentence of some sort'
words = s.split()
acceptable = lambda x: len(x) > 3
print(len(words) == len(list(filter(acceptable, words))))

甚至:

s = 'this is a sentence of some sort'
words = s.split()
res = all(len(word) > 3 for word in words)
print(res)

或者,正如@pault 建议的那样:

s = 'this is a sentence of some sort'
all(len(w) > 3 and w.islower() for w in s.split())

【讨论】:

  • + 这不是 RegEx 任务
  • 1 OP 想要一个正则表达式解决方案。 2 使用 all 函数在纯 Python 中执行该测试有一种更有效的方法,该函数会在特定单词未通过测试时立即短路。
  • 或者干脆all(len(w) => 3 and w.islower() for w in s.split())
【解决方案2】:

这是一种无需正则表达式的方法:

def all_words_three_or_more(sentence):
  sentence_list = sentence.split(' ')
  for word in sentence_list:
    if len(word) < 3 or word.lower() != word:
      return False
  return True

测试用例:

test_str_true = "this string will succeed"
test_str_false = "this string is false" 
test_str_false_caps = "FAIL THIS BECAUSE CAPS"

print(all_words_three_or_more(test_str_true)) # true
print(all_words_three_or_more(test_str_false)) # false
print(all_words_three_or_more(test_str_false_caps)) #false

【讨论】:

  • 你可以使用word.islower()而不是word.lower() != word
【解决方案3】:

请试一试:

import re
pattern = re.compile('([a-z\s]{3,})+$')
all(pattern.match(x) for x in  "hello world".split())

输出:

True

all(pattern.match(x) for x in  "hi world".split())

输出:

False

【讨论】:

    【解决方案4】:

    如前所述,这可能不是需要正则表达式的问题,但问题可能是使用正则表达式是正确方法的更大问题的简化。

    我的解决方案不是检查每个单词是否符合您的要求,而是尝试查找任何不符合您要求的单词。这意味着我们正在寻找:

    1. 任何不是小写字母或空白字符的字符
    2. 小于最小长度的单词 (3)

    导致以下正则表达式:

    1. [^a-z\s]
    2. (^|\s)[a-z]{1,2}(\s|$)

    将这些组合在一起得到:([^a-z\s])|((^|\s)[a-z]{1,2}(\s|$))。这给出了以下可用的 Python 代码:

    import re
    pattern = '([^a-z\s])|((^|\s)[a-z]{1,2}(\s|$))'
    
    result1 = not bool(re.search(pattern, 'hello world'))
    result2 = not bool(re.search(pattern, 'hi world'))
    

    【讨论】:

      【解决方案5】:

      你也可以试试这个,

      (?m)^(?=\s*([a-z]{3,}\s*)*$).*
      

      Demo

      【讨论】:

        猜你喜欢
        • 2010-12-29
        • 2013-01-23
        • 1970-01-01
        • 2012-02-21
        • 1970-01-01
        • 2015-09-08
        • 2014-11-22
        • 1970-01-01
        • 2011-04-10
        相关资源
        最近更新 更多