1

Thanks to Kobi I just resolve the problem of checking all the permutations without repetition for a given string "abbc". This is the solution

(?:(?<A>a)|(?<B>b)|(?<C>c)){4}(?<-A>)(?<-B>){2}(?<-C>)

The expression has to have one "a", two "b" and one "c" in 4 consecutive characters.

Now I need something more complicated, I need to check a expression with 2 blocks of permutations:

  1. In the first 6 positions it has to find all the permutations of "abccc" but adding to each one a character in the 3rd position that can be any of them (a, b or c).
  2. In the second block it has to find all the permutations of "abccc"

I don't know if I have explained myself well, but:

  1. For the first 6 positions it has to have one a, one b, 3 c and in the 3rd position any value (a,b or c) no matter the order except for the 3rd position that can be any
  2. For the next 5 positions it has to have one a, one b and 3 c no matter the order.

I'm trying to explain it the best way possible. I'm sorry it looked like a copy-paste which is not.

The regex I'm looking for is "abXccc-abccc" where X could be a, b or c and the - separate the 2 blocks, although they are together I'm adding the - because for the first 6 characters I have to look for all the combinations and for the last 5 the same.

It doesn't have to be this way, it could be something similar, this is just an example. It could be "aabXXcc-abbc" for example.

nhahtdh
  • 55,989
  • 15
  • 126
  • 162
John Mathison
  • 904
  • 1
  • 11
  • 36
  • You may want to provide your attempt so far. Right now, this sounds like a copy-pasted homework assignment that you expect others to do. – Anonymous Jun 10 '15 at 12:57
  • https://stackoverflow.com/help/how-to-ask – Doro Jun 10 '15 at 13:06
  • I made a program to calculate all the combinations of the no repetition permutations and I compared one by one, the times were so high with 900 millions iterations, that's the reason I'm trying to figure out how to do it with regex. This way I only have to do 2 millions iterations. I'm new using regex and I don't know how to start... – John Mathison Jun 10 '15 at 14:09
  • 2
    I've added answer, I hope it explains how to combine these blocks. I realize you may not want the dash there but you can simple remove it. You should have no problem combining different groups, like `aabXXcc-abbc`, using this approach. By the way - you are in luck you are using .Net - other regex flavors do not have this feature, and I think this solution is (relatively) simple. – Kobi Jun 10 '15 at 14:45

1 Answers1

2

It is simple to adapt the previous pattern to the new one.

The second block is straightforward:

(?:(?<A>a)|(?<B>b)|(?<C>c)){5}(?<-A>)(?<-B>)(?<-C>){3}

Next, the only thing you need to know is that you can specify the same group more than once. This is explained in Martin Büttner's answer, which I've linked before.

So, the first block, with [abc] on the first position, can be written as:

(?:(?<A>a)|(?<B>b)|(?<C>c)){2}[abc](?:(?<A>a)|(?<B>b)|(?<C>c)){3}(?<-A>)(?<-B>)(?<-C>){3}

Combined:

(?:(?<A>a)|(?<B>b)|(?<C>c)){2}[abc](?:(?<A>a)|(?<B>b)|(?<C>c)){3}(?<-A>)(?<-B>)(?<-C>){3}-(?:(?<A>a)|(?<B>b)|(?<C>c)){5}(?<-A>)(?<-B>)(?<-C>){3}

Or, with the Ignore Whitespace flag:

(?:(?<A>a)|(?<B>b)|(?<C>c)){2}  # Match 2 a, b, or c's
[abc]                           # Match a, b, or c, but don't push to stack.
(?:(?<A>a)|(?<B>b)|(?<C>c)){3}  # Match 3 a, b, or c's
(?<-A>)(?<-B>)(?<-C>){3}        # Check we've matched 1 a, 1 b and 3 c's.
-                               # match the dash
(?:(?<A>a)|(?<B>b)|(?<C>c)){5}  # Match 5 a, b, or c's
(?<-A>)(?<-B>)(?<-C>){3}        # Check we've matched 1 a, 1 b and 3 c's.

This is not as elegant (it has some repetition), but should still be simple to understand as a next step of the previous question.

Working example at Regex Storm

Community
  • 1
  • 1
Kobi
  • 135,331
  • 41
  • 252
  • 292