in reply to regex for string

The reason a single, 'pure and simple' regex is not a good approach to this problem is that it has great difficulty handling the degenerate cases of zero-length and single-character strings: either some fancy footwork is needed within the regex, or some sort of post-match fixup must be done in these cases.

For a single-character string in particular, one is asking the regex to match twice on the same character! A regex will always advance the string match point (as returned by the pos built-in) past the match or, in the case of a zero-width assertion match, by a default of one character. (The 5.10 regex 'backtracking control verbs' may offer a way around this problem, but I'm not familiar enough with them to know.)

The following is the best I can do with a regex. It uses post-match fixup to finish the job. Note that the order of the alternatives in the ordered alternation
    \A . | . \z | \z
is important: the lone  \z alternative must be last.

>perl -wMstrict -le "for my $str (@ARGV) { printf qq{string '$str': }; my ($first, $last) = $str =~ m{ \A . | . \z | \z }xmsg; $last = $first if not $last; print qq{first '$first', last '$last'}; } " "" "a" "ab" "abc" "abcd" string '': first '', last '' string 'a': first 'a', last 'a' string 'ab': first 'a', last 'b' string 'abc': first 'a', last 'c' string 'abcd': first 'a', last 'd'