我要强制在字符串中包含4个不同的字符。

有效的例子:

"1q2w3e4r5t"
"abcd"

无效的示例:

"good"
"1ab1"

有模式的想法吗?

===============>>#1 票数:3

您应该考虑使用非正则表达式解决方案。 我只写此答案以显示针对此问题的更简单的正则表达式解决方案。

初始解决方案

这是一个更简单的正则表达式解决方案,它断言字符串中至少有4个不同的字符:

(.).*?((?!\1).).*?((?!\1|\2).).*?((?!\1|\2|\3).).*

regex101上的演示 (PCRE和Java具有与此regex相同的行为)

.*?((?!\\1).).*?((?!\\1|\\2).) ,...搜索之前未出现的下一个字符,这是通过检查字符与先前捕获组中捕获的字符不同。

从逻辑上讲,量词的懒惰/贪婪在这里并不重要。 惰性量词.*? 用于使搜索从最近没有出现的最接近的字符开始,而不是从最远的字符开始。 由于可以减少回溯,因此在匹配情况下应该可以稍微提高性能。

String.matches() ,它断言整个字符串与正则表达式匹配:

input.matches("(.).*?((?!\\1).).*?((?!\\1|\\2).).*?((?!\\1|\\2|\\3).).*")

改进的解决方案

如果您担心性能:

(.)(?>.*?((?!\1).))(?>.*?((?!\1|\2).))(?>.*?((?!\1|\2|\3).)).*

regex101上的演示

使用String.matches()

input.matches("(.)(?>.*?((?!\\1).))(?>.*?((?!\\1|\\2).))(?>.*?((?!\\1|\\2|\\3).)).*")

从内部模式退出后, (?>pattern)构造可防止回溯到组中。 这用于将捕获组“锁定”到每个不同字符的首次出现,因为即使在字符串的后面选择了另一个字符,结果也是相同的。

此正则表达式的行为与普通程序相同,该程序从左到右循环,根据一组不同的字符检查当前字符,如果当前字符不在该字符集中,则将其添加到该字符集中。

由于这个原因,惰性量词.*? 变得重要,因为它会搜索到目前为止尚未出现的最接近的字符。

===============>>#2 票数:1

您可以像这样计算不同字符的数量:

String s = "abcdefaa";
long numDistinctChars = s.chars().distinct().count()

或者,如果不是在Java 8上(我无法提出更好的东西):

Set<Character> set = new HashSet<>();
char[] charArray = s.toCharArray();
for (char c : charArray) {
    set.add(Character.valueOf(c));
}
int numDistinctChars = set.size();

===============>>#3 票数:1 已采纳

您可以使用正则表达式对此进行验证,并使用否定的前瞻性检查所捕获的字母数字字符是否不相同4次。

我会说这很丑,但是可​​以工作:

String rx = "^(.).*?((?!\\1).).*?((?!\\1|\\2).).*?((?!\\1|\\2|\\3).).*?$"

观看演示

IDEONE演示

String re = "^(.).*?((?!\\1).).*?((?!\\1|\\2).).*?((?!\\1|\\2|\\3).).*?$"; 
// Good
System.out.println("1q2w3e4r5t".matches(re));
System.out.println("goody".matches(re));
System.out.println("gggoooggoofr".matches(re));
// Bad
System.out.println("good".matches(re));
System.out.println("1ab1".matches(re));

输出:

true
true
true
false
false

  ask by Igor translate from so

未解决问题?本站智能推荐:

1回复

验证包含正则表达式中模板的字符串

我在尝试验证此字符串时遇到问题... 因此,用户选择一个模板: q( ) 。 然后,用户将括号内的内容填入,结果可能像这样: q(a,b,c) 我尝试过使用正则表达式验证此String的其他方法,但它始终返回答案“否”。 我相信问题是我的正则表达式中的"q("和")"
3回复

正则表达式以查看字符串是否包含模式

我是正则表达式的新手,但发现执行此简单任务非常困难。 整个字符串看起来像 我只需要检查此字符串中是否*.out/text" not found类似*.out/text" not found东西。在这种情况下它确实存在,但是我没有得到正确的输出 我使用的正则表达式为.*\\*\\.
2回复

检查字符串是否包含正则表达式匹配

我要检查的是在String任意位置是否有数字后跟空格和另一个数字,且中间没有任何"," 目前我正在这样做: 而且效果很好。 但是我想知道是否还有其他更简单的方法来实现这一目标?
3回复

正则表达式检查字符串是否包含年份

我想要一个与今年匹配的正则表达式,用连字符分隔。 例子 基本上,每年应该只允许使用4位数字,且不得少于或大于4位,并且应使用连字符分隔。 直到1986- 当我尝试这样的事情 {4}在去年给出了模式错误。 请帮助我如何在模式末尾添加{4}
3回复

正则表达式测试字符串是否包含数字

我想测试一个字符串是否包含数字(至少一个数字),所以我尝试了这个: 不幸的是,如果条款打印出来,它不包含任何数字。 我使用正则表达式错了吗?
4回复

正则表达式检查字符串中是否重复字符

我有一个用于username的字符串,它可以包含(period) . (下划线) _ 。 但是我不希望字符串重复超过1个. 或_ 。 因此,例如: alpha.beta.gamma和alpha.beta_gamma是可以接受的 。 alpha..beta , alpha__b
2回复

正则表达式包含多个字符串

我对理解正则表达式有很多问题,我不确定我要做什么。 我希望一个正则表达式能够与以任何顺序包含“ a”和“ b”的字符串匹配。 范例: 比赛 比赛 不匹配 是否可以借助正则表达式来做到这一点? 提前致谢
3回复

用于字符串的正则表达式包含

我需要知道给定的字符串是否包含任何字符*.=,? 或: 我尝试过(使用str.contains ): [*?=:]和 [^*?=:]和 ^[*?=:] 他们似乎都不起作用。 有人可以让我知道正则表达式吗?
2回复

正则表达式字符串不包含?

我正在尝试创建一个正则表达式来查找包含以下内容的文本: src .js 并且不包含问号“?” 与此同时。 例如,我希望我的正则表达式匹配: 不匹配: 因为它包含一个问号符号。 谁能给我合适的正则表达式 ? 非常感谢
2回复

正则表达式-匹配不包含字符串的模式

我见过其他类似的问题,但它们都是关于结尾处匹配的问题,这不是我想要的。 我想用语法匹配参数: {{param-name}}或{{param-name=default value}} 到目前为止,我有以下正则表达式: 但是问题是,如果有多个参数,它将仅创建一个匹配项:从第