Search code examples
regexswapsubstitutionregex-lookarounds

Regex for reordered characters of a given string


I am trying to find a regex matching reordered string 0046711766. So, exactly two 0s, two 1s, one 4, three 6s and two 7s in any order. After searching StackOverflow I made this

(?=([^0]*0){2}) (?=([^1]*1){2}) (?=([^6]*6){3}) (?=([^7]*7){2}) (?=.*4) [01467]{10}

which seems to do a job. But I had no prior experience with positive lookaheads and probably there is a more effective way to do it. As far as I understand it, the most limiting of my conditions is actually at the end, which is bad for applying such search in a database.


Solution

  • That's true that the most limiting condition is currently at the end, but if it were at the beginning, you wouldn't be able to use lookahead assertions (you'd need lookbehind assertions instead).

    But the lookbehind assertions need to be fixed-width (there are some exceptions, e.g. in Java), so you cannot really use them here.

    There is one thing you could do, though, and that is using the lookahead assertion for the main condition.

    So this is your current solution with minor improvements (demo):

    (?=([^0]*0){2})(?=([^1]*1){2})(?=[^4]*4)(?=([^6]*6){3})(?=([^7]*7){2})[01467]{10}
    

    And this is the version with an extra lookahead (demo) (edit: I made the groups inside lookaheads non-capturing):

    (?=[01467]{10})(?=(?:[^0]*0){2})(?=(?:[^1]*1){2})(?=[^4]*4)(?=(?:[^6]*6){3})(?=(?:[^7]*7){2}).{10}