Regex 不同字符数的正则表达式

Regex 不同字符数的正则表达式,regex,Regex,假设我希望在字符串的不同字符少于k时匹配正则表达式。也就是说,如果k=2,它将匹配aaaa或a,但不匹配abc。正则表达式可以这样做吗?如果可以,我可以将变量k传递给匹配表达式吗?这是可能的,但它需要您构造正则表达式,而不仅仅是替换正则表达式中的一个数并使用它 与其搜索少于或等于k不同字符的字符串,不如让我们搜索多于k不同字符的字符串 对于k=1: ^(.).*?((?!\1).) 这将匹配具有2个或更多不同字符(即严格大于1个字符)的任何字符串 对于k=2: ^(.).*?((?!\1).)

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

这是可能的,但它需要您构造正则表达式,而不仅仅是替换正则表达式中的一个数并使用它

与其搜索少于或等于
k
不同字符的字符串,不如让我们搜索多于
k
不同字符的字符串

对于
k
=1:

^(.).*?((?!\1).)
这将匹配具有2个或更多不同字符(即严格大于1个字符)的任何字符串

对于
k
=2:

^(.).*?((?!\1).).*?((?!\1|\2).)
^(?!(.).*?((?!\1).).*?((?!\1|\2).))
与上面相同,这将匹配任何具有3个或更多不同字符的字符串

我们可以将其扩展到更高的
k
,方法是在末尾添加更多的
*?((?!…)
,其中负前瞻中的模式将检查前面捕获组中捕获的所有字符的交替

^(?!(.)(?:\1)*((?!\1).)(?:\1|\2)*((?!\1|\2).))
回到最初的问题,我们只需要将模式放在一个负前瞻中的
^
后面,以否定它匹配的内容

作为
k
=2的示例:

^(.).*?((?!\1).).*?((?!\1|\2).)
^(?!(.).*?((?!\1).).*?((?!\1|\2).))
如果字符串具有
k
或更少的不同字符,则上述模式将仅返回一个匹配项(空字符串,因为字符串
^
的开头和负前瞻是零宽度)

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

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

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

你所说的角色类型是什么意思?你是说
k
不同的字符吗?你可能可以使用负环视来实现这一点,但我认为你必须为
k
的每个值定制regexp。这似乎比正则表达式更容易处理字符串处理代码。@Barmar是的,这就是我的意思。那么您是否试图匹配一个仅由字母a或变量a中的任何字符值组成的字符串,该字符串的字符数为k或更少,但至少为1?如果是这样的话,那么这就行了,假设您是在一种编程语言中进行此操作的,在这种语言中会发生替换:
a{1,k}$
。如果我是你,我只需要使用正则表达式来获取你想要的字符类型,并将字符串拆分为单个字符,对它们进行排序,唯一化,然后测试长度。