如何高效提取地址字符串中的城市名?替代遍历匹配的优化方案
高效提取英国地址中的城市名
思路1:利用英国邮编的固定格式定位
英国邮编有规范的格式(比如YO10 3EU,结构为「1-2个字母+数字+空格+数字+2个字母」),城市通常在邮编的前一个逗号分隔项里。我们可以先匹配出邮编,再反向提取前面的城市部分。
代码实现:
$location_string = 'Lawrence Street, York, YO10 3EU, United Kingdom'; // 匹配英国邮编的正则 $postcodePattern = '/[A-Z]{1,2}[0-9][A-Z0-9]? [0-9][A-Z]{2}/i'; if (preg_match($postcodePattern, $location_string, $matches)) { // 截取邮编前的内容 $partBeforePostcode = substr($location_string, 0, strpos($location_string, $matches[0])); // 取最后一个逗号后的内容作为城市,去除首尾空格 $city = trim(end(explode(',', $partBeforePostcode))); } else { // 无邮编的情况(如'Hertford, Hertfordshire, England, United Kingdom') // 取第一个逗号前的内容作为城市 $city = trim(strtok($location_string, ',')); } echo $city; // 输出 York 或 Hertford
思路2:基于地址层级分割筛选
英国地址的层级一般是「街道 → 城市 → 郡/邮编 → 地区 → 国家」,我们可以把地址按逗号分割成数组,再通过特征筛选城市:
- 排除带数字的项(街道含门牌号、邮编带数字)
- 排除已知的地区/国家/郡关键词
代码实现:
$location_string = 'Hertford, Hertfordshire, England, United Kingdom'; // 可补充更多常见郡/地区名 $excludeTerms = ['england', 'scotland', 'wales', 'northern ireland', 'united kingdom', 'hertfordshire', 'yorkshire']; $parts = array_map('trim', explode(',', $location_string)); foreach ($parts as $part) { $lowerPart = strtolower($part); // 筛选出不含数字且不在排除列表里的项 if (!preg_match('/\d/', $part) && !in_array($lowerPart, $excludeTerms)) { $city = $part; break; // 第一个符合条件的就是城市 } } echo $city; // 输出 Hertford
比原方法高效的原因
- 不用手动维护庞大的城市列表,避免遗漏或重复更新
- 无需遍历数组逐个匹配,通过正则或特征筛选一次定位,执行效率更高
- 适配多种地址格式,扩展性更强
内容的提问来源于stack exchange,提问作者user19846605
相关产品推荐
相关产品推荐

