假设我有一组字符[ABC]
。我正在寻找一个与超集的任何排列匹配的正则表达式,除了空集,即。
ABC ACB BAC BCA CAB CBA
AB BC AC CB CA BA
A B C
正则表达式(显然)不匹配空字符串。
P.S。表达相同目标的另一种方法是“匹配至少包含一次集合中每个字符的任何非空字符串”。
更新:集合[ABC]
只是一个例子,因为真实集合也可能更大。有了这个问题,我希望找到一个“通用”解决方案而不是[ABC]
的特定解决方案。
答案 0 :(得分:6)
我相信这可以通过正则表达式来解决。使用此正则表达式:
/^([ABC])(?!\1)([ABC])?(?!\1|\2)[ABC]?$/
如果您需要在线演示,请告诉我。
答案 1 :(得分:3)
感谢你的回答(尤其是anubhava和codaddict),我能够找到这个解决方案,我觉得它非常优雅,因为它只允许输入一次:
\b(([ABC])(?!.*\2))+\b
需要\b
来匹配完整的字词;省略它们也会找到关于所需属性的子词。要匹配一个完整的字符串,你显然会这样做:
^(([ABC])(?!.*\2))+$
答案 2 :(得分:1)
这不是正则表达式擅长的东西。您可能只想创建一个排列列表,然后生成所有唯一的子串。
类似的东西:
def matches(s, characters):
if len(s) != len(set(s)):
return False # not unique sequence of characters
return set(s).issubsetof(set(characters))
答案 3 :(得分:1)
尝试:
([ABC]?)(?!.*\1)([ABC]?)(?!.*\2)[ABC]?
只有[ABC]?
重复3次,并添加了对不允许重复字符的否定先行断言的检查。
请注意,仅当输入集全部唯一时才会起作用。
答案 4 :(得分:1)
"A((B?C?)|(C?B?))|B((A?C?)|(C?A?))|C((A?B?)|(B?A?))"
它是A | B | C,每个都可以跟随一对可选值
A(B?C?) matches A, AB,AC and ABC
A(C?B?) matches A, AC,AB and ACB
但不是ACAC,AA或ACC。 B或C作为第一个字符的情况是等价的。
对于更长的字符串,这很快就会变得难看。更好的方法是(伪代码):
string.sort().matches ("^A?B?C?$") && string.length > 0
答案 5 :(得分:0)
试试这个:(更新)
A[BC](?![ABC])|B[AC](?![ABC])|C[AB](?![ABC])|[ABC](?![ABC])|(ABC|ACB|BAC|BCA|CAB|CBA)(?![ABC])
演示:
答案 6 :(得分:0)
这是我的版本:
\b(?=[ABC]{1,3})([ABC]{1})(?:(?!\1)([ABC]{1})(?:(?!\1)(?!\2)[ABC]{1})?)?\b
逻辑:
\b
:寻找单词边界(?=[ABC]{1,3})
:预见是否存在长度= 3的字符串,其值仅为A,B,C ([ABC]{1})
:匹配第一个字符
然后可选择(?!\1)([ABC]{1})
:检查下一个字符是否与先前匹配的字符不同 - 如果不匹配,则匹配
并可选择(?!\1)(?!\2)[ABC]{1}
:检查下一个字符是否与之前匹配的字符1或2不同 - 如果不匹配,则匹配字符我针对此输入进行了测试,因此看起来非常可靠:
AABCC BBCC AB BC AC CB CA BA A B C. ABC ACB BAC BCA CAB CBA AAA ABB AAA BBC AA
编辑:
正如你所提到的,字符集可能更大我会在你的问题中遵循PS建议并按以下方式执行:
引入chars
数组,该数组将每个字符保存在允许的集合中(将字符串拆分为字符)
获取一个inputStrings
数组(在空白处或其他任何需要的地方拆分输入字符串)
string
中的每个inputStrings
{
string.length <= inputStrings.length
matches
列表中找到的匹配项数matches
列表是否包含任何条目,然后检查所有条目是否== 1或0
} 答案 7 :(得分:0)
好吧,我必须说我已经考虑了很多问题 - 因为你似乎想要一些真正普遍和可定制的东西(以尽可能多地支持元素等) - 这就是我认为会做的最佳解决方案。
从数学的角度来看,你想要的是识别一组元素的所有排列而不重复。
查找集合的所有排列,带重复(并将它们存储在数组中)
[ABC]([ABC]{1,2})?
旁注:假设您有一个包含n
元素的集合,您所要做的就是:
[elements]([elements]{1,n-1})?
使用重复元素过滤所有排列
PHP中的示例代码:
<?php
function strToArray($str)
{
$i = 0;
while (isset($str[$i]))
{
$result[$i] = $str[$i];
$i++;
}
return $result;
}
function noDuplicates($str)
{
if (array_unique(strToArray($str))==strToArray($str)) return true;
else return false;
}
$AAA = "AAA";
$ABC = "ABC";
if (noDuplicates($AAA)) echo "$AAA : ok"; else echo "$AAA : not ok\n";
if (noDuplicates($ABC)) echo "$ABC : ok"; else echo "$ABC : not ok\n";
?>
输出
AAA : not ok
ABC : ok