regex - RegEx:以任意顺序匹配包含唯一组的字符串
问题描述
澄清:我需要这个正则表达式才能在 ECMAScript 中工作。
我想找到一个匹配的正则表达式:
- 出现给定次数的独特组(当然至少一次),
- 以任何顺序。
为简单起见,让我们假设(现在)每个组只是一个字符。
然后,对于组大小为 1、2 和 3 的 3 个(唯一)组/字符(这些是任意参数),我们希望匹配:
aaabbc
xxxyyz
ababac
ccbabc
以下内容不应匹配:
aaaaaa
aaabbcc
aabbcd
有关更多示例,请参阅此链接:https ://regex101.com/r/zpNLHw/2
尝试的解决方案
使用正前瞻和负前瞻来强制组是唯一的(首先,捕获第一组,然后在捕获第二组时,在之前插入负前瞻以确保第二组与第一组不同,等等。 )。
在前瞻之后,只需附加
^.{total_number_of_characters}$
(在本例中为3 + 2 + 1 = 6
)。
产生的正则表达式:
(?=.*(.).*\1.*\1)(?=.*(?!\1)(.).*\2)(?=.*(?!\1|\2)(.))^.{6}$
这个尝试的解决方案似乎部分起作用 - 它没有给出错误匹配,但只给出了所需匹配的子集(有关详细信息,请参阅上面的链接)。
正确匹配:
aabccc
aabbbc
aaabbc
错过的比赛(应该匹配但不匹配):
abbccc
abbbcc
aaabcc
解决方案
逻辑是你需要先在这里检查更长的模式。原因是,一旦前瞻是原子的(至少,在您使用的正则表达式风格中),并且一旦找到匹配项,当正则表达式引擎尝试回溯时,它们就永远不会重新输入/重新评估。
如果以aaadcc
输入为例,您将很容易看到会发生什么。该^(?=.*(.).*\1.*\1)(?=.*(?!\1)(.))(?=.*(?!\1|\2)(.).*\3).{6}$
模式首先检查 3 个相同的字符,然后检查与 Grpup 1 中捕获的字符不相等的单个字符,然后搜索除第 1 组和第 2 组之外的两个字符。看看:
- 一旦正则表达式引擎找到三个
a
s 并a
保存在第 1 组缓冲区中,就会退出第一个前瞻。 - 第二个前瞻的工作方式如下:
.*
匹配整个aaadcc
字符串,然后触发负前瞻并通过,但(.)
失败(因为有字符串的结尾)。因此,引擎回溯,并将字符(.)
匹配并捕获到第 2 组。c
(?=.*(?!\1|\2)(.).*\3)
现在搜索不等于a
andc
并且至少重复两次的字符 - 但d
字符串中只有一个。由于前瞻是原子的,因此不会发生重新评估,并且会发生故障。
注意:如果您使用非原子前瞻(如 PCRE2 中的那些),您将获得预期的结果:
^(?*.*(.).*\1.*\1)(?*.*(?!\1)(.))(?*.*(?!\1|\2)(.).*\3).{6}$
推荐阅读
- json - 在 Swift 4 中使用可编码解析嵌套的 JSON
- python - 在 $PATH 中找不到可接受的 C 编译器 - 安装 Python 和 GCC
- php - 函数 create_function 在 PHP 7.2 中已弃用
- c# - 向应用程序各处的用户一次加载数据的推荐方法是什么?
- python - 在python中制作计算器,这种方法明智吗?
- c# - 是否可以从一个集合启动 TFS 构建到另一个集合?
- javascript - 反射型 XSS:为什么必须将攻击载荷反射到受害者的浏览器?
- google-sheets - 单元格根据单元格范围改变颜色
- flutter - 如何将下拉菜单项字符串传递给 fetchData() Json 对象
- java - Java价值短缺中的减法