PHP实现街道名称与含字母门牌号拆分的技术求助
解决街道名与带字母门牌号的拆分问题
我来帮你搞定这个地址拆分的难题!你之前的代码问题在于正则表达式的逻辑不对,导致要么街道名被错误截断,要么门牌号的字母丢失,下面给你正确的解决方案:
问题分析
先说说你之前代码的问题:
- 第一个正则
preg_replace("/[^A-Z]+/", "", $straat):这个规则会删掉所有非大写字母的内容,包括空格、小写字母和数字,比如输入Sample street 12会变成SAMPLESTREET,完全不是正确的街道名。 - 第二个正则
preg_match_all('!\d+!', $str, $matches):只匹配纯数字序列,遇到1A这种带字母的门牌号,只会提取出1,丢失了后面的字母部分。
正确解决方案
我们可以用一个精准的正则表达式,一次性匹配出街道名和带字母的门牌号,支持纯数字门牌号(如12)和带字母的门牌号(如1A、23B):
// 获取原始地址 $full_address = $order->get_shipping_address_1(); // 先去掉首尾多余空格,避免干扰匹配 $trimmed_address = trim($full_address); // 匹配街道名和门牌号的正则 $pattern = '/^(.*?)\s+(\d+[A-Za-z]*)$/'; if (preg_match($pattern, $trimmed_address, $matches)) { // 提取街道名,再次trim去掉可能的末尾空格 $street_name = trim($matches[1]); // 提取门牌号(包含数字和后续字母) $house_number = $matches[2]; } else { // 如果地址格式不符合预期(比如没有门牌号),做 fallback 处理 $street_name = $trimmed_address; $house_number = ''; } // 测试输出示例 echo "街道名:{$street_name}\n"; echo "门牌号:{$house_number}\n";
正则说明
这个正则/^(.*?)\s+(\d+[A-Za-z]*)$/的逻辑:
^:匹配字符串的开头(.*?):非贪婪匹配前面的所有内容,确保准确停在门牌号前的空格处,不会过度匹配\s+:匹配一个或多个空格(分隔街道名和门牌号)(\d+[A-Za-z]*):匹配门牌号:一个或多个数字,后面可以跟0个或多个字母(支持12、1A、34BC这类格式)$:匹配字符串的结尾
扩展调整
如果你的场景中门牌号的字母可能在数字前面(比如A12),可以把正则调整为:
$pattern = '/^(.*?)\s+([A-Za-z]*\d+[A-Za-z]*)$/';
这样就能匹配任意位置带字母的门牌号了。
内容的提问来源于stack exchange,提问作者NSsem
相关产品推荐
相关产品推荐

