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 |