diff --git a/pyap/source_US/data.py b/pyap/source_US/data.py index 987290a..3c378a6 100644 --- a/pyap/source_US/data.py +++ b/pyap/source_US/data.py @@ -110,6 +110,76 @@ def str_list_to_upper_lower_regex(str_list: List[str]) -> str: from_to="{1,5}", ) + +def states_abbrvs_regex() -> str: + # Some abbreviations are non-standard + _STATE_ABBRS = { + "AL", + "AK", + "AZ", + "AR", + "CA", + "CO", + "CT", + "DE", + "FL", + "GA", + "HI", + "ID", + "IL", + "IN", + "IA", + "KS", + "KY", + "LA", + "ME", + "MD", + "MA", + "MI(?:CH)?\.?", + "MN", + "MS", + "MO", + "MT", + "NE", + "NV", + "NH", + "NJ", + "NM", + "NY|N\.Y\.", + "NC", + "ND", + "OH", + "OK", + "OR", + "PA", + "RI", + "SC", + "SD", + "TN", + "TX", + "UT", + "VT", + "VA", + "WA", + "WV", + "WI", + "WY", + } + _NON_STATE_ABBRS = { + "AS", + "GU", + "MP", + "PR", + "VI", + "D\.?C\.?", + } + return ( + r"(?:" + + str_list_to_upper_lower_regex(list(_STATE_ABBRS | _NON_STATE_ABBRS)) + + r")(?![A-Za-z])" + ) + + """ Regexp for matching street name. In example below: @@ -192,6 +262,12 @@ def str_list_to_upper_lower_regex(str_list: List[str]) -> str: r"""(?:[Aa][Ll][Tt]|[Aa][Ll][Tt][Ee][Rr][Nn][Aa][Tt][Ee])\ \d{1,4}(?!\d)""" ) +# Some states name their state-maintained highways by the state abbreviation +# and the number. +numbered_state_highway = r"""(?:{states}\ \d{{1,4}}(?!\d))""".format( + states=states_abbrvs_regex() +) + # Used to handle edge cases where streets don't have a street type: # eg. `55 HIGHPOINT`, `600 HIGHWAY 32` numbered_or_typeless_street_name = r""" @@ -211,6 +287,8 @@ def str_list_to_upper_lower_regex(str_list: List[str]) -> str: {numbered_route_re} | {numbered_alternate} + | + {numbered_state_highway} ) ) """.format( @@ -223,6 +301,7 @@ def str_list_to_upper_lower_regex(str_list: List[str]) -> str: numbered_road_re=numbered_road_re, numbered_route_re=numbered_route_re, numbered_alternate=numbered_alternate, + numbered_state_highway=numbered_state_highway, ) post_direction = r""" @@ -1094,75 +1173,6 @@ def street_type_extended(idx: str) -> str: ) -def states_abbrvs_regex() -> str: - # Some abbreviations are non-standard - _STATE_ABBRS = { - "AL", - "AK", - "AZ", - "AR", - "CA", - "CO", - "CT", - "DE", - "FL", - "GA", - "HI", - "ID", - "IL", - "IN", - "IA", - "KS", - "KY", - "LA", - "ME", - "MD", - "MA", - "MI(?:CH)?\.?", - "MN", - "MS", - "MO", - "MT", - "NE", - "NV", - "NH", - "NJ", - "NM", - "NY|N\.Y\.", - "NC", - "ND", - "OH", - "OK", - "OR", - "PA", - "RI", - "SC", - "SD", - "TN", - "TX", - "UT", - "VT", - "VA", - "WA", - "WV", - "WI", - "WY", - } - _NON_STATE_ABBRS = { - "AS", - "GU", - "MP", - "PR", - "VI", - "D\.?C\.?", - } - return ( - r"(?:" - + str_list_to_upper_lower_regex(list(_STATE_ABBRS | _NON_STATE_ABBRS)) - + r")(?![A-Za-z])" - ) - - # region1 is actually a "state" def make_region1(idx: Optional[str] = None): maybe_idx = f"_{idx}" if idx else "" diff --git a/tests/test_parser_us.py b/tests/test_parser_us.py index f27f3eb..8b51c98 100644 --- a/tests/test_parser_us.py +++ b/tests/test_parser_us.py @@ -524,6 +524,7 @@ def test_po_box_positive(input, expected): ("82 ALBRO TRACT", True), ("6123 SHEFFIELD HOUSE", True), ("99 Valley Greens Dr\nSouth Tower", True), + ("612 NC 54 Apt B77", True), # negative assertions ("6 95 34 75 COMPANY PHONE IS", False), (", 666 Hell ST PMB 29700", False), @@ -663,6 +664,7 @@ def test_full_street_positive(input, expected): ("1234 Fowlstown Rd Lot#18 \nBainbridge, GA 39817", True), ("1234 LONG LANE\nB2 \nUPPER DARBY PA 19082", True), ("567-55 Arlington Terrace Fl1 \nJamaica, NY 11435", True), + ("612 NC 54 Apt B77 \nCarrboro, NC 27510-6105", True), # negative assertions ("123 Nw Awesome Drive\n12345", False), ("ONE HEALING CENTER LLC, 16444", False),