in reply to Regex: matching character which happens exactly once

Here you go, this passes all of my test cases:

/^(?(?=((?(3)(?(?!.*\3)(?(?!((?<=(?!\3).(?=(?2)). |(?=\3)..)))(*F))))(?(?=.)(?=(.)(?1)))))(*F))/sx

Simple!*

Replies are listed 'Best First'.
Re^2: Regex: matching character which happens exactly once (updated)
by haukex (Archbishop) on Oct 24, 2017 at 11:24 UTC

    Duh, it's actually much simpler, and this one even captures the single character(s)! (Update 2: See Variable-Width Lookbehind (hacked via recursion))

    /(.)(?!((?<=(?!\1).(?=(?2)).|(?=\1)..))|.*\1)/s

    Of course, right after I said I was "done" with this topic, I realized that the "recursive lookbehind" technique can be used on its own, without all that complicated lookahead logic, since that's what the regex engine and backtracking are for ;-)

    qr{ (?<cur> . ) #(?(?= (?&lookback) | .* \g{cur} ) # (?{print "cur($+{cur}) seen before or after\n"}) # (*FAIL) #) # simpler: (?! (?&lookback) | .* \g{cur} ) (?{ print "post: $-[0]<$&>$+[0]\n" }) (?(DEFINE) (?<lookback> (?<= (?<prev> (?! \g{cur} ) . ) (?{ print " prev: <$+{prev}> / $-[0]<".($&//'-').">$+[0]\ +n" }) (?=(?&lookback)) . | (?= \g{cur} ) . . ) ) ) }msx

    Update: Another smaller simplification ((*FAIL) isn't needed).

Re^2: Regex: matching character which happens exactly once
by LanX (Saint) on Nov 12, 2017 at 20:28 UTC
    Hauke

    I kept your replies on my growing to-do list but I'm realising now that I'm won't be able to "dive" into the matter again.

    Thanks for your help, I'm closing the case now.

    > Rolf, I blame you for the sleep I lost over this!

    And thanks for taking care of my insomnia. ;-p

    Honestly, while the use case is very exotic I learned a lot about the various corners of the regex features. I hope for you too!

    Der Weg war das Ziel! :)

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!