« first day (4 days earlier)      last day (1323 days later) » 

11:35 AM
I solved "match strings with no unique characters", on domain ^.*$, in PCRE, in 33 characters (so obviously without enumerating the charset).
And it uses a widely applicable technique, easily generalizable to string-lists with no unique strings, for example.
Regexes available if you want to see them.
 
 
5 hours later…
4:19 PM
@Grimy I would like to see that please. (Unique characters. As for the perfect powers one, I'm going to try that later.)
 
4:55 PM
^((.)((?<=(?=\n|\2.*\2|(?3)).)))*$
3
This is emulating variable-length look-behind by recursively look-behinding a single char
 
Hahaha! Nice. I would have guessed PCRE would be boring and protect against that somehow.
Why do you use \n instead of ^?
 
Not the same
\n never matches, since the domain is ^.*$
But without it, PCRE complains “recursive call could loop indefinitely”
There are lots of ways around that, including wrapping the entire (?=foo) as (?(?=foo)|(*F))
 
How about \0
 
5:10 PM
That would give wrong results for strings that contain \0
For domain ^[\n\N]*$ (aka arbitrary strings), the shortest I have is

^(?s:(.)((?<=(?=\1.*\1).|(?=(?2)).)))*$
 
I don't think PCRE can process \0 in a string, because it's written in C, which uses \0-terminated strings.
\n however, can be inside ^.*$
In non-/m mode
 
/m? /s is what causes . to match \n, and it’s not the default
By default . is a synonym for \N
 
/m is what causes ^ and $ to match on newlines in addition to the beginning and end of the string.
all /s does is make . match newlines, which you can do without it using \X or [\s\S] or [\d\D] etc.
Even with /m, you can still match the true beginning and end of the string with \A and \z.
 
My point is, without /s, ^.*$ cannot contain newlines
Since . doesn’t match newlines
I specified the domain as ^.*$ in order to exclude newlines
 
My point is, it's less universal than it can be. \0 would be more universal.
I challenge you to get PCRE to parse a \0 inside a string
 
5:23 PM
pcretest does it just fine:
re> /\0/
data> \0
0: \x00
[^\0]* isn’t any more universal than .*
 
Why not just use ^((.)((?<=(?=.^|\2.*\2|(?3)).)))*$
Although for full strings, even when not in /m mode, ^((.)((?<=(?=.^|\2.*\2|(?3)).)))*\z is needed
 
5:42 PM
Oh right .^ is much shorter than .(?!)
 
@Grimy Published this as a method for matching a character occurring exactly once.
 
Yay
 

« first day (4 days earlier)      last day (1323 days later) »