I still think it's likely the OP is taking the wrong approach by trying to hand-roll a JSON decoder, so I did want to point out a few issues with your code - hopefully thereby also pointing out some of the pitfalls of hand-rolled approaches.
- High surrogates range from U+D800 to U+DBFF, which your regex doesn't cover (e.g. unpack("H*", encode("UTF-16BE", "\N{VARIATION SELECTOR-256}")) eq "db40ddef").
- Your regexes should probably also handle uppercase hex digits.
- You might want to pass Encode::FB_CROAK to decode.
- You don't need to loop over the strings with a regex and then a second regex, that's fairly inefficient; it can all be done in one regex.