【问题标题】:Regex (Python) - Match words with two or more distinct vowels正则表达式 (Python) - 匹配具有两个或多个不同元音的单词
【发布时间】:2018-04-28 13:52:40
【问题描述】:

我正在尝试匹配包含两个或多个不同元音的字符串中的单词。问题可以限制为小写。

string = 'pool pound polio papa pick pair'

预期结果:

pound, polio, pair

poolpapa 会失败,因为它们只包含一个不同的元音。但是,polio 很好,因为即使它包含两个 os,它也包含两个不同的元音(io)。 mississippi 会失败,但albuquerque 会通过)。

思考过程:使用环视,大概五次(忽略大写),用括号括起来,然后是{2}。比如:

re.findall(r'\w*((?=a{1})|(?=e{1})|(?=i{1})|(?=o{1})|(?=u{1})){2}\w*', string)

但是,这匹配所有六个单词。

我杀死了{1}s,这使它更漂亮({1}s 似乎没有必要),但它仍然返回所有六个:

re.findall(r'\w*((?=a)|(?=e)|(?=i)|(?=o)|(?=u))\w*', string)

提前感谢您的帮助。我检查了其他查询,包括"How to find words with two vowels",但似乎没有一个足够接近。另外,我正在寻找纯正则表达式。

【问题讨论】:

  • “{1} 似乎没有必要”表明您不太了解它的作用。括号使事情不清楚,但我认为您不能重复前瞻两次 - 如果语法允许(显然它确实如此,因为否则您会收到错误),那么它会测试相同的前瞻 两次.

标签: python regex


【解决方案1】:

您不需要 5 个单独的前瞻,这完全是矫枉过正。只需捕获capture group 中的第一个元音,然后使用negative lookahead 来断言它与第二个元音不同:

[a-z]*([aeiou])[a-z]*(?!\1)[aeiou][a-z]*

See the online demo.

【讨论】:

  • 太好了,谢谢。这似乎是“捕获群体”,而那个时髦的小“\1”将是我的下一个研究重点。再次感谢!
【解决方案2】:

您的 \w*((?=a)|(?=e)|(?=i)|(?=o)|(?=u))\w* 正则表达式匹配所有至少有 1 个任意元音的单词。 \w* 匹配 0+ 个单词字符,因此第一个模式会抓取整个字母、数字和下划线。然后,回溯开始,正则表达式引擎尝试查找后面跟着aeiou 的位置。一旦找到该位置,之前抓取的单词字符就会再次被抓取并与尾随的 \w* 一起使用。

要将整个单词与至少 2 个不同的元音匹配,您可以使用

\b(?=\w*([aeiou])\w*(?!\1)[aeiou])\w+

请参阅regex demo

详情

  • \b - 字边界
  • (?=\w*([aeiou])\w*(?!\1)[aeiou]) - 一个positive lookahead,紧靠当前位置的左侧,需要
    • \w* - 0+ 字字符
    • ([aeiou]) - Capturing group 1(其值在模式后面用\1 backreference 引用):任何元音
    • \w* - 0+ 个单词字符
    • (?!\1)[aeiou] - [aeiou] 集合中的任何元音不等于存储在第 1 组中的元音(由于负前瞻 (?!\1) 导致匹配失败,如果在当前位置的右侧,@987654325 @模式匹配找到)
  • \w+ - 1 个或多个单词字符。

【讨论】:

    【解决方案3】:

    匹配字符串中至少包含两个不同元音且字符数最少的单词(据我所知):\w*([aeiou])\w*(?!\1)[aeiou]\w*

    演示:https://regex101.com/r/uRgVVa/1

    解释:

    • \w*:匹配 0 个或多个单词字符。您不需要以单词边界 (\b) 开头,因为\w 不包含空格,因此使用\b 将是多余的。

    • ([aeiou]): [aeiou] 匹配任何一个元音。它在括号中,因此我们可以参考稍后匹配的元音。这些第一个括号内的任何内容都是第 1 组。

    • \w*:匹配 0 个或多个单词字符。

    • (?!\1):表示后面的正则表达式不能和第1组选择的字符相同。例如,如果第1组匹配的元音是a,下面的正则表达式不能是a。这由 \1 调用,它引用在组 1 中选择的字符(例如,如果 a 匹配组 1,\1 引用 a)。 ?! 是一个否定的前瞻,表示括号外的以下正则表达式与 ?! 后面的内容不匹配。

    • \w*:匹配 0 个或多个单词字符。

    【讨论】:

      猜你喜欢
      • 2022-11-14
      • 1970-01-01
      • 2015-01-31
      • 1970-01-01
      • 1970-01-01
      • 2021-06-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多