正则表达式的不同字符数

时间:2014-11-16 23:39:56

标签: regex

假设我希望每当字符串的字符数少于k时匹配正则表达式。也就是说,如果k=2,则匹配aaaaa但不匹配abc。正则表达式可以这样做,如果是这样,我可以将变量k传递给匹配表达式吗?

1 个答案:

答案 0 :(得分:1)

这是可能的,但它需要你构造正则表达式,而不仅仅是用正则表达式中的数字代替它并完成它。

不要搜索小于或等于k个不同字符的字符串,而是让我们搜索严格超过k个不同字符的字符串。

对于k = 1:

^(.).*?((?!\1).)

这将匹配任何包含2个或更多不同字符的字符串(即严格超过1个字符)。

k = 2:

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

与上面相同,这将匹配任何具有3个或更多不同字符的字符串。

我们可以通过在结尾添加更多k来将此扩展到更高.*?((?!...).),其中负面预测中的模式将检查已捕获的所有字符的交替前面的捕获组。

回到原来的问题,我们只需要将^之后的模式放在负面预测中,以否定它匹配的内容。

作为k = 2的示例:

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

上面的模式只返回一个匹配(一个空字符串,因为字符串^的开头,负前瞻是零宽度)iff字符串有k或更少不同字符。

请注意,此方法有一个警告。由于捕获组和反向引用的数量随k的增加而增加,因此它可能会超出模式中允许的捕获组数量限制。

正则表达式在较高k时效率较低,其中最坏的情况是具有k个不同字符的字符串。一种方法是更改​​构造以限制.*?部分仅匹配先前捕获组中捕获的字符。

^(?!(.)(?:\1)*((?!\1).)(?:\1|\2)*((?!\1|\2).))