This appears to be a situation when the pattern matches a zero-length substring (see perlre, "Repeated patterns matching zero-length substring"). Using s/.+/t/g gives the expected result.
Update: Adding use re 'debug'; to the code produces some interesting output that illustrates the documented behavior. Note how it says Matching REx ".*" against "" <stuff deleted> Match successful! midway through. If I understand this correctly, that is where it matches the empty string and produces the extra 't' in the output.
Compiling REx `.*'
size 3 Got 28 bytes for offset annotations.
first at 2
1: STAR(3)
2: REG_ANY(0)
3: END(0)
anchored(MBOL) implicit minlen 0
Offsets: [3]
2[1] 1[1] 3[0]
Matching REx ".*" against "abc"
Setting an EVAL scope, savestack=5
0 <> <abc> | 1: STAR
REG_ANY can match 3 times out of 2147483647
+...
Setting an EVAL scope, savestack=5
3 <abc> <> | 3: END
Match successful!
Matching REx ".*" against ""
Setting an EVAL scope, savestack=5
3 <abc> <> | 1: STAR
REG_ANY can match 0 times out of 2147483647
+...
Setting an EVAL scope, savestack=5
3 <abc> <> | 3: END
Match successful!
Matching REx ".*" against ""
Setting an EVAL scope, savestack=5
3 <abc> <> | 1: STAR
REG_ANY can match 0 times out of 2147483647
+...
Setting an EVAL scope, savestack=5
3 <abc> <> | 3: END
Match possible, but length=0 is smaller than requested=1, failing!
failed...
Match failed
ttFreeing REx: `".*"'
See perldebguts for more information on interpreting this output.
|