In the case of passing a city and state, the HTML you're getting back isn't matched by the sequence of regular expressions you're using. After first matching
$data =~ /----------</g;
you try for
while ($data =~ /\G(br>(\d{5}))/ig) {
which won't ever match, at least not until the USPS changes the format of the data they're returning. Take a very careful look at the return data to see why not.
One easy way to fix this is to change that to
while ($data =~ /\G(.*?<br>)(\d{5})/ig) {