in reply to form parsing, hex, HTML formatting

That first regular expression is translating hex encoded characters back into regular characters. For example, if it sees %20, it will translate that into a space.

W/r/t the second question--yes, that looks like it's causing the spaces instead of carriage returns. \x20 is a space character (\x20 = hex 20, so space in ASCII).

You could change that to:

$sub_body =~ s/\n/<br>/g;
Try that and see if it works for you.