我有以下代码:
preg_match("/^(.+)[,\\s]+(.+?)\s*(\d{5})?$/", trim($searchbox), $matches);
list($arr['add'], $arr['city'], $arr['state']) = $matches;
$citystr = trim(str_replace(',', '', $arr['city']));
$statestr = trim($arr['state']);
当有人输入“加利福尼亚花岗岩湾”时,这很有效,但我想修改它以便在有人遗漏“CA”部分时抓住它。所以,如果有人只输入“花岗岩湾”,上面的代码就是把“海湾”作为国家 - 这没什么好处的。如果有人在“Granite Bay,CA 00000”这样的末尾添加了一个拉链,它也会失败
我是否可以对此RegEx进行任何修改以避免这两种情况?
TIA
答案 0 :(得分:2)
是的,您可以构建一个不太宽松/更详细的模式:
^\h*([^,\s]+(?:\h+[^,\s]+)*+)\h*(?:,\h*([A-Z]+))?\h*(\d{5})?\h*$
([^,\s]+(?:\h+[^,\s]+)*+)
将城市名称捕获为:不以空格开头或结尾的内容,最终分成几个部分。
(?:,\h*([A-Z]+))?
使所有状态部分都可选。请注意,我只为状态选择了大写字母,但您也可以使其不区分大小写,因为重要的一点是逗号,所以无关紧要。
顺便说一句,如果你想确定进入用户的内容,每个信息使用一个字段(一个用于城市,一个用于州,一个用于邮政编码)。
答案 1 :(得分:2)
你可以去:
^ # start of the string
(?P<town>[A-Z][^,]+) # uppercase, followed by not a comma
(?> # a non-capturing group
,\h*\K # a comma, horizontal whitespace, \K
(?P<state>[A-Z]{2}) # two UPPERCASE letters
)? # make the whole group optional
请参阅a demo on regex101.com
可以肯定的是,您可能需要一些城镇和州的数据库来检查(上面的表达式允许XY
表示状态),或者@Casimir指出,使用几个字段每个信息。