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

时间:2014-09-05 10:29:06

标签: java regex string

我有很多这样的人物: A B B C D

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

有没有办法使用正则表达式来匹配可以由"拖动"形成的任何字符串。可用的字符进入空格?

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

A B C
A B B
B C B
D A B

但这些都是无效的:

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

很抱歉,如果之前已经被问过。

3 个答案:

答案 0 :(得分:8)

vks's solution would work properly,这是通过添加来优化以实现“_ _ _”规则:

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

Here is a regex demo

原始正则表达式的更改:

  • 捕获组被删除,因为我们使用Java - Java正则表达式实现专门用于在匹配期间编写捕获的组。)
  • 为了正则表达式的可读性,锚^被移到前面。

正则表达式解释:

  • ^在比赛开始时断言位置。
  • (?!否定前瞻 - 断言我们的位置匹配以下内容,而不移动指针:
  • (?:[^A]*A){2}两个“A” s(文字字符),非“A”以最佳方式滚动。
  • )关闭小组。
  • (?!(?:[^B]*B){3})与上述论坛相同 - 断言比赛中“B” s。
  • (?!(?:[^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();
}

答案 1 :(得分:5)

 (?!(.*?A){2,})(?!(.*?B){3,})(?!((.*?C){2,}))(?!((.*?D){2,}))^[ABCD]*$

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

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

答案 2 :(得分:2)

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

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

已使用(?m) MULTILINE modifier其中^匹配行开头和$行结束。

Test at regexplanet(点击Java); regex101(非Java)


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

  • (?!.*([ACD]).*\1)在行开始^使用负面预测,通过将[ACD]捕获到{{1}来确保[ACD]最多出现一次并且检查,它不会在任何地方出现两次。

  • \1使用否定前瞻,确保(?!(?>.*?B){3})最多出现 2x

  • 最后B确定总可用字符集,确保格式化,每个字母必须由空格预先确定或开始并检查长度。

这可以很容易地修改为其他需求。另请参阅SO Regex FAQ