首先,我知道这是您通常不使用正则表达式的问题,我只是想找出这是否可能。
话虽这么说,我想做的是匹配所有字符串排列的所有匹配项(目前,我不在乎重叠的匹配项是否匹配);例如,如果我有字符串abc
,我想匹配所有出现的abc
,acb
,bac
,bca
,cab
和cba
。
到目前为止,我使用的是以下正则表达式:(?:([abc])(?!.{0,1}\1)){3}
(注意:我知道我可以使用+
而不是{0,1}
,但这仅适用于长度为3的字符串) 。这种工作方式是有效的,但是如果两个排列彼此相邻,并且第一个字母与第二个字母太接近(例如abc cba
→c c
),则第一个排列不匹配。是否可以使用正则表达式解决此问题?
答案 0 :(得分:1)
直接接触
[abc]{3}
将匹配太多结果,因为它也将匹配aab
。
为了避免对a
进行双重匹配,您需要从随后的a[bc]{2}
组中删除一个。
a[bc]{2}
将匹配太多结果,因为它也将匹配'abb'。
为了避免对b
进行双重匹配,您需要从后面的组中删除一个,以留下ab[c]{1}
或abc
的简称。
abc
不会匹配所有组合,因此您需要另一个组。
(abc)|([abc]{3})
,将再次匹配太多组合。
这条路将带您走到将所有排列明确地分组列出的道路上。
您可以创建组合以便不需要写出所有组合吗?
(abc)|(acb)
可能像a((bc)|(cb))
一样世俗。
(bc)|(cb)
我无法再将其缩短。
匹配过多并删除不需要的
根据正则表达式引擎,您可能可以将AND
表示为前瞻,以便删除匹配项。这不是消耗它。
(?=[abc]{3})(?=(?!a.a))[abc]{3}
与aca不匹配。
此问题现在与上述类似,您需要删除所有可能违反排列的组合。在此示例中,这是包含相同字符多个时间的任何表达式。
'(。)\ 1+'此表达式多次使用分组引用来匹配相同的字符,但是需要知道表达式中存在多少组并且非常脆弱添加组会杀死表达式((.)\1+)
no更长的比赛。存在相对的反向引用,并且需要您的特定正则表达式引擎的知识。 \k<-1>
可能是您想要的。我会假设使用.net,因为我碰巧为此添加了一个正则表达式测试器。
我要排除的排列是:nn.
n.n
.nn
nnn
因此,我创建了以下模式:((?<1>.)\k<1>.)
((?<2>.).\k<2>)
(.(?<3>.)\k<3>)
((?<4>.)\k<4>\k<4>)
将所有内容放在一起会给我这样的表达,请注意,我在.net中使用了相对反向引用-您的使用期限可能会有所不同。
(?=[abc]{3})(?=(?!((?<1>.)\k<1>.)))(?=(?!((?<2>.).\k<2>)))(?=(?!(.(?<3>.)\k<3>)))(?=(?!((?<4>.)\k<4>\k<4>)))[abc]{3}
对于特定长度,答案是肯定的。