【问题标题】:How to match words with no vowel?如何匹配没有元音的单词?
【发布时间】:2019-12-23 18:41:57
【问题描述】:

元音和周围的世界可能是主观的,所以我有这些规则:

  • 元音是 a、e、i、o、u 中的任何一个。不是。
  • 单词是英文字母 a-z、A-Z 的序列。
  • \n,(逗号)、.(句点)或(空格)不是单词的一部分。

我有以下字符串:

text = """line with every word a vowel
sntshk xx yy.
Okay zz fine."""

我的尝试:

s = re.findall(r'[^aeiouAEIOU].*', text)
print(s)

期望:

['sntshk', 'xx', 'yy', 'zz']

现实:

['line with every word a vowel', '\nsntshk xx yy.', '\nOkay zz fine.']

相关:Search all words with no vowels

【问题讨论】:

  • 是否应该匹配 hhh_111hh111 之类的字符串?
  • 不行,看上面一个词的定义。

标签: python regex


【解决方案1】:

在不区分大小写的模式下,我只会使用\b[^AEIOU_0-9\W]+\b 模式:

text = """line with every word a vowel
sntshk xx yy.
Okay zz fine."""

re.findall(r'\b[^AEIOU_0-9\W]+\b', text, flags=re.I)
print(s)

['sntshk', 'xx', 'yy', 'zz']

模式[^\W] 实际上是一个双重否定,表示任何单词字符。对于这个否定类,我们将元音、数字和下划线列入黑名单,只留下辅音。

【讨论】:

  • 你应该在否定字符类中添加_\d,否则它将匹配hhh_111hhh_wwwhh111
【解决方案2】:

使用由字母字符组成的普通字符集,不包括元音,每端都有单词边界:

(?i)\b[b-df-hj-np-tv-z]+\b

https://regex101.com/r/DqGuY1/1

  • (?i) - 不区分大小写匹配
  • \b - 字边界
  • [b-df-hj-np-tv-z]+ - 重复以下一项或多项:
    • b-df-hj-np-tv-z 范围内的字符
  • \b - 字边界

更易读,但不太优雅,您也可以使用

(?i)\b(?:(?![eiou])[b-z])+\b

【讨论】:

  • ? 那是什么……那是什么?你愿意解释一下吗?
  • 字符集中的破折号将匹配从破折号左侧字符到右侧字符范围内的任何字符。例如[a-c] 将匹配abc,我只是继续该模式并排除元音
  • 你能解释一下(?:(?![eiou])[b-z])位吗?
  • 它匹配bz之间的字符,同时(在否定前瞻中)确保匹配的字符不在[eiou]的字符集中
  • 我对@9​​87654341@ 的事情还是有点困惑。 ?
【解决方案3】:
[^aeiouAEIOU]

这意味着匹配除aeiouAEIOU 之外的任何字符,因此它也会匹配字母以外的字符,这不是必需的,因为您只想获取单词,

所以只需匹配除元音以外的所有字母

\b[bcdfghjklmnpqrstvwxyz]+\b

Regex Demo

【讨论】:

  • 所有回复中最简单的。 ??
【解决方案4】:

有一种纯 Python 方式,无需任何导入即可执行此操作:

[x.strip('.') for x in text.split() if all(y.lower() not in 'aeiou' for y in x)]

示例

text = """line with every word a vowel 
sntshk xx yy.
Okay zz fine."""

print([x.strip('.') for x in text.split() if all(y.lower() not in 'aeiou' for y in x)])
# ['sntshk', 'xx', 'yy', 'zz']

【讨论】:

    【解决方案5】:

    这行得通:

    text = """line with every word a vowel
    sntshk xx yy.
    Okay zz fine."""
    q = ''
    s = text.split()
    for i in range(len(s)):
        c = 0
        s[i] = s[i].strip('.')
        for c in range(len(s[i])):
            if (s[i])[c].lower() in 'aeiou':
                q += s[i]+' '
                break
    print(q)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多