RegExp匹配由一组有限字符组成的字符串,而不重用任何字符

我有很多像这样的人物: ABBCD

我有几个像这样的空格: _ _ _

有没有办法使用正则表达式匹配任何可以通过“拖动”可用字符到空白空间形成的字符串?

所以在这个例子中,这些是一些有效的匹配:

ABC ABB BCB DAB 

但这些都是无效的:

 AAB // Only one 'A' is available in the set BBB // Only two 'B's are available in the set 

对不起,如果之前已经被询问过。

vks的解决方案可以正常工作 ,并且这里通过添加来优化以实现“_ _ _”规则:

 ^(?!(?:[^A]*A){2})(?!(?:[^B]*B){3})(?!(?:[^C]*C){2})(?!(?:[^D]*D){2})(?:[ABCD](?:\s|$)){3} 

这是一个正则表达式演示 。

原始正则表达式的变化:

  • 由于我们使用Java,因此删除捕获组 – Java正则表达式实现在匹配期间花费时间编写捕获的组。
  • ^在前面移动以便于正则表达式的可读性。

正则表达式解释:

  • ^在比赛开始时断言位置。
  • (?! Negative lookahead – 断言我们的位置与以下内容匹配,而不移动指针:
  • (?:[^A]*A){2}两个“A” (字面字符),非“A”以最佳方式翻转。
  • )关闭小组。
  • (?!(?:[^B]*B){3})与上述组相同 – 断言匹配中没有三个“B”
  • (?!(?:[^C]*C){2})断言匹配中没有两个“C”
  • (?!(?:[^D]*D){2})断言匹配中没有两个“D”
  • (?:非捕获组:匹配以下内容而不捕获。
  • [ABCD]列表“A”“B”“C”“D”中的任何字符。
  • (?:\s|$)一个空格,或字符串的结尾。
  • ){3}三次 – 必须完全匹配序列三次才能满足“_ _ _”规则。

要使用正则表达式:

 boolean fulfillsRule(String str) { Pattern tripleRule = Pattern.compile("^(?!(?:[^A]*A){2})(?!(?:[^B]*B){3})(?!(?:[^C]*C){2})(?!(?:[^D]*D){2})(?:[ABCD](?:\s|$)){3}"); return tripleRule.matcher(str).find(); } 
  (?!(.*?A){2,})(?!(.*?B){3,})(?!((.*?C){2,}))(?!((.*?D){2,}))^[ABCD]*$ 

你可以使用这样的东西。参见演示。

http://regex101.com/r/uH3fV3/1

有趣的问题,这是我的想法:

 (?m)^(?!.*([ACD]).*\1)(?!(?>.*?B){3})(?>[AD] ){2}[AD]$ 

使用(?m) MULTILINE 修饰符 ,其中^匹配行开始和$ line结束。

在regexplanet上测试 (点击Java); regex101 (非Java)


如果我理解正确,可用的字符组是A,B,B,C,D 。 如果字符串在您的示例中包含每个[ACD] 0或1B 0-2 ,则该字符串应该有效。 我的模式由3部分组成:

  • (?!.*([ACD]).*\1)用于行开始^负前瞻以确保[ACD]最多发生一次,通过捕获[ACD]\1并检查,它确实在任何地方都不会发生

  • (?!(?>.*?B){3})使用负前瞻,确保B最多出现2次

  • finally (?>[AD] ){2}[AD]$确定总可用字符集,确保格式化,每个字母必须由空格预先确定或开始并检查长度。

这可以很容易地修改为其他需求。 另请参阅SO Regex常见问题解答