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!*

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

qr{ (?(DEFINE) (?<loopfwd> (?{ print "pre: $-[0]<$&>$+[0] pos:".pos."\n" }) (?(<cur>) # we have a current character to inspect (?{ print "*CUR: <$+{cur}> / $-[0]<$&>$+[0] pos:".pos."\n" + }) (?(?! .* \g{cur} ) (?{ print " cur($+{cur}) doesn't repeat ahead, looking + back\n" }) (?(?!(?&loopback)) (?<= (?<single> . ) ) (?{ print " cur($+{cur}) doesn't repeat behind eit +her, " ."FOUND SINGLE: '$+{single}'!\n" }) (*FAIL) | (?{ print " cur($+{cur}) repeats behind\n" }) ) | (?{ print " cur($+{cur}) cur repeats ahead\n" }) ) ) (?(?=.) # there are more characters, continue looping (?= (?<cur>.) (?&loopfwd) ) ) (?{ print "post: $-[0]<$&>$+[0] pos:".pos."\n" }) ) ) (?(DEFINE) (?<loopback> (?<= # this lookbehind is fixed width! (?<prev> (?! \g{cur} ) . ) (?{ print " prev: <$+{prev}> / $-[0]<$&>$+[0] pos:".pos." +\n" }) (?=(?&loopback)) . | (?= \g{cur} ) . . ) ) ) \A (?(?=(?&loopfwd)) (?{ print "loopfwd matched (no single found)\n" }) (*FAIL) | (?{ print "loopfwd didn't match (single found)\n" }) ) }msx

It turns out the trick is to anchor the string at the beginning and use zero-width assertions everywhere in order to implement a "loop over every character in this string" algorithm, and you implement the loops as recursion. And you can "loop" backwards from the current character with a "fixed-width" lookbehind!

The one thing I haven't figured out yet is getting the single value out of the regex. Another thing to note is that I had to invert the condition twice, since (*FAIL) breaks out of recursion but (*ACCEPT) does not. But I'll leave that for others, I'm done for now :-P

* Just kidding ;-) I slept quite well, which probably helped :-)

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
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!