我正在尝试匹配包含两个或更多不同元音的字符串中的单词。问题可以限制为小写。
string ='pool pound polio papa pick pair'
预期结果:
p p,小儿麻痹症,对池和爸爸会失败,因为它们只包含一个不同的元音。然而,脊髓灰质炎很好,因为即使它包含两个'o',它包含两个不同的元音('i'和'o')。密西西比会失败,但阿尔伯克基会失败。
思考过程:使用一个环视,可能是五次(忽略大写),用括号括起来,然后用{2}。类似的东西:
re.findall(r'\w*((?=a{1})|(?=e{1})|(?=i{1})|(?=o{1})|(?=u{1})){2}\w*', string)
然而,这与所有六个单词匹配。
我杀死了{1},这使得它更漂亮({1}似乎没必要),但它仍然会返回所有六个:
re.findall(r'\w*((?=a)|(?=e)|(?=i)|(?=o)|(?=u))\w*', string)
提前感谢您的任何帮助。我检查了其他查询,包括"How to find words with two vowels",但似乎都没有。另外,我正在寻找纯粹的RegEx。
答案 0 :(得分:4)
你不需要5个独立的前瞻,这是完全矫枉过正的。只需捕获capture group中的第一个元音,然后使用negative lookahead断言它与第二个元音不同:
[a-z]*([aeiou])[a-z]*(?!\1)[aeiou][a-z]*
答案 1 :(得分:3)
您的\w*((?=a)|(?=e)|(?=i)|(?=o)|(?=u))\w*
正则表达式匹配所有至少包含1个元音的单词。 \w*
匹配0+单词字符,因此第一个模式抓取整个字母,数字和下划线。然后,回溯开始,正则表达式引擎尝试查找跟随a
,e
,i
,o
或u
的位置。一旦找到该位置,之前抓取的单词字符将再次被追踪并使用尾随\w*
。
要匹配包含至少2个不同元音的整个单词,您可以使用
\b(?=\w*([aeiou])\w*(?!\1)[aeiou])\w+
请参阅regex demo。
<强>详情
\b
- 字边界(?=\w*([aeiou])\w*(?!\1)[aeiou])
- 一个positive lookahead,位于当前位置的左侧,需要
\w*
- 0+ word chars ([aeiou])
- Capturing group 1(其值在模式后面以\1
backreference引用):任何元音\w*
- 0+ word chars (?!\1)[aeiou]
- 来自[aeiou]
集合的任何元音都不等于存储在第1组中的元音(由于否定前瞻(?!\1)
未通过匹配,如果,立即到在当前位置的右侧,找到lookahead模式匹配)\w+
- 一个或多个单词字符。