如何在 java 中使用正则表达式否定元音条件

How to negate a vowel condition using Regex in java

我正在尝试为应具有以下条件的字符串构建正则表达式:

  1. 必须至少包含一个元音。
  2. 它不能包含三个连续的元音或三个连续的辅音。
  3. 不能连续出现两次相同的字母,'ee' 或 'oo' 除外。

我无法为第二个和第三个条件构造正则表达式。

例如: 凉亭 - 接受, 苹果 - 不接受, miiixer - 不被接受, 对冲 - 不被接受, 喂养 - 接受

提前致谢!

已编辑:

我的代码:

Pattern ptn = Pattern.compile("((.*[A-Za-z0-9]*)(.*[aeiou|AEIOU]+)(.*[@#$%]).*)(.*[^a]{3}.*)");
Matcher mtch = ptn.matcher("zoggax");

if (mtch.find()) {
        return true;
    }
else
    return false;

假设 'y' 是非元音字母,这应该适用于英语;

^(?!.*[aeiou]{3})(?!.*[bcdfghjklmnpqrstvwxyz]{3})(?!.*([^eo])).*[aeiou]

解释:

  • ^ 将匹配固定到字符串的开头。
  • (?!.*[aeiou]{3}) 检查您在字符串中当前位置之后的任何位置都找不到 3 个连续的元音。 (因为这是在 ^ 之后立即检查整个字符串)。它也不会使光标前进。
  • 非元音字母测试类似。如果您的正则表达式风格支持集合减法,则可以以更漂亮的方式完成此操作。但是我认为Java不会这样做。
  • (?!.*([^eo])) 检查没有出现单个字符捕获组,除了 e 或 o 之外的字符,后面跟着它自己的副本。 IE。除了 e 和 o 之外,没有其他字符重复两次。
  • .*[aeiou] 在字符串中的某个位置查找元音。

此正则表达式还假定设置了不区分大小写的标志。我认为这是 java 的默认值,但我对此可能是错误的。

它也是一个正则表达式,可以在满足您条件的字符串中找到匹配项。它不一定会匹配整个字符串。 - 如果需要,将 .*$ 添加到正则表达式的末尾。

以下应该适合您的需要:

(?=.*[aeiouy])(?!.*[aeiouy]{3})(?!.*[a-z&&[^aeiouy]]{3})(?!.*([a-z&&[^eo]])\1).*

在Java中:

String regex = "(?=.*[aeiouy])(?!.*[aeiouy]{3})(?!.*[a-z&&[^aeiouy]]{3})(?!.*([a-z&&[^eo]])\1).*";
System.out.println("bower".matches(regex));
System.out.println("appple".matches(regex));
System.out.println("miiixer".matches(regex));
System.out.println("hedding".matches(regex));
System.out.println("feeding".matches(regex));

打印:

true
false
false
false
true

解释:

  • (?=.*[aeiouy]):至少包含一个元音
  • (?!.*[aeiouy]{3}): 不包含3个连续元音
  • (?!.*[a-z&&[^aeiouy]]{3}):不含3个连续辅音
    • [a-z&&[^aeiouy]]az 之间的任何字母,但 aeiouy
    • 的 none
  • (?!.*([a-z&&[^eo]])):不包含2个连续字母,除了eo
    • [a-z&&[^eo]]az之间的任何字母,但eo
    • 的none

参见 http://www.regular-expressions.info/charclassintersect.html

如果我的直觉是正确的,你的意思是 "three consecutive occurrences of the same letter"(看你的例子)那么你可以简单地说 "eo 可能不会出现 三次 ,其他所有情况可能不会出现 两次 " ,像这样:

^(?=.*[aeiouy].*)(?!.*([eo]).*)(?!.*([a-df-np-z]).*).*$

Debuggex Demo,关键是出现三次的字母是出现两次。