$re = '~^
(?P<street>[^-\n]+)
(?:-\h*)?
(?P<town>(?:(?!\b[A-Z]{2}\b).)*)
(?P<state>\b[A-Z]{2}\b)?\h*
(?P<zip>[-\d]*)
$~xm';
$str = '123 Ave Ave - Hoquiam WA 98103
123 Ave Ave - Hoquiam, WA 98103
123 Ave Ave - Hoquiam, WA 98103-1345
123 Ave Ave - Hoquiam
123 Ave Ave - Ocean Shores WA
123 Ave Ave - Ocean Shores, WA
123 Ave Ave - D\'ile, WA
123 Ave Ave
';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
// Print the entire match result
var_dump($matches);
Please keep in mind that these code samples are automatically generated and are not guaranteed to work. If you find any syntax errors, feel free to submit a bug report. For a full regex reference for PHP, please visit: http://php.net/manual/en/ref.pcre.php