【问题标题】:Regex: Match all permutations [duplicate]正则表达式:匹配所有排列[重复]
【发布时间】:2019-01-16 10:03:14
【问题描述】:

首先,我知道这是一个你通常不会使用正则表达式的问题,我只是想知道这是否可能。

话虽如此,我要做的是匹配字符串的任何排列的所有出现(现在,我不在乎重叠出现是否匹配);例如,如果我有字符串abc,我想匹配所有出现的abcacbbacbcacabcba

到目前为止,我拥有的是以下正则表达式:(?:([abc])(?!.{0,1}\1)){3}(注意:我知道我可以使用+ 而不是{0,1},但这仅适用于长度为 3 的字符串)。这种工作,但如果有两个排列相邻,其中第一个的字母与第二个的字母太接近(例如abc cbac c),第一个排列不匹配.是否可以使用正则表达式解决这个问题?

【问题讨论】:

  • . 替换为[abc]。或至少\S[^ ]
  • @WiktorStribiżew 好主意,但这仍然不匹配,例如。 abc 中的 abcccab...
  • ([abc])(?!\1)([abc])(?!\1|\2)[abc]?见regex101.com/r/D5OOcD/1
  • @WiktorStribiżew 这也是我考虑的一个选项,但只要我的模式超过 3 个字符(例如abcd),我就需要显着更改正则表达式;因此,我想知道是否有可能获得一个正则表达式,我真的只需要插入模式及其长度并且它总是有效
  • 不,普通的正则表达式是不可能的。

标签: regex


【解决方案1】:

直接接近

[abc]{3} 会匹配太多结果,因为它也会匹配aab。 为了不重复匹配a,您需要从后面的组中删除一个a[bc]{2}

a[bc]{2} 会匹配太多结果,因为它也会匹配 'abb'。 为了不重复匹配b,您需要从后面的组中删除a,留下ab[c]{1}abc 简称。

abc 不会匹配所有组合,因此您需要另一个组。

(abc)|([abc]{3}) 会再次匹配太多组合。

这条路径将引导您将所有排列明确列在组中。

你可以创建组合,这样你就不需要写出所有的组合了吗?

(abc)|(acb) 可以写成a((bc)|(cb))

(bc)|(cb)我不能再缩短了。

匹配太多并删除不需要的

根据正则表达式引擎,您可以将AND 表示为前瞻,以便您可以删除匹配项。 THIS 而不是 THAT 消耗 THIS。

(?=[abc]{3})(?=(?!a.a))[abc]{3} 不会匹配 aca。

这个问题现在类似于上面的问题,您需要删除所有违反排列的组合。在此示例中,它是包含多次相同字符的任何表达式。

'(.)\1+' 这个表达式自己使用分组引用多次匹配同一个字符,但需要知道表达式中存在多少组并且非常脆弱添加组会杀死表达式((.)\1+)不再匹配.存在相对反向引用,需要了解您的特定正则表达式引擎。 \k<-1> 可能是您想要的。我将假设 .net,因为我碰巧有一个正则表达式测试器为此添加书签。

我要排除的排列是:nn.n.n.nnnnn

所以我创建了这些模式:((?<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}

对于特定长度,答案是肯定的。

Here is some testing data.

【讨论】:

    猜你喜欢
    • 2011-03-07
    • 1970-01-01
    • 2013-12-30
    • 2015-12-26
    • 2013-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多