首页 > 作文

PHP智能识别收货地址信息实例

更新时间:2023-04-06 16:36:05 阅读: 评论:0

功能需求:用户输入混合的收货地址,能智能识别出地址,手机,姓名

准备:需要两张表,一张地区表和一张姓氏表 (地区表得到应该不难,姓氏表我是搜索中国姓氏自制的哈,底部会附上表结构)

思路:主要思路分两种,一种是用户正常输入全地址,则顺序按地区等级匹配地址;另一种用户非正常输入(省市区有缺少的),则全面模糊搜索表,再根据结果对比原地址。

提醒:手机可以根据自己需求修改正则;

名字只匹配中文,可以根据自己的需求修改姓氏表以及正则

地址匹配暂无发现问题

效果图:

代码:

<?phpclass distinguishaddress {/*** 类的入口方法* 传入地址信息自动识别,并返回最高匹配结果* 如果地址新增,则需要删除缓存文件重新缓存* @param $address**/function getaddressresult($address){// 优先第一种方法$result = $this->getaddressarrar($address);// 如果结果不理想,再模糊去匹配if($result['level'] != 3){$result_sub = $this->addressvague($address);// 只有全匹配对才替换,否则不做任何改变if($result_sub['level'] == 3){$result = $result_sub;}}// 联系方式-优先匹配电话if(preg_match('/1\d{10}少儿绘本/', $address, $mobiles)){ // 手机$result['mobile'] = $mobiles[0];} el if(preg_match('/(\d{3,4}-)?\d{7,8}/', $address, $mobiles)){ // 固定电话$result['mobile'] = $mobiles[0];}// 识别姓名-必须空格分享的--概率preg_match_all('/[\x{4e00}-\x{9fa5}]{2,}/iu', $address,$names);if($names){$name_where = '';foreach ($names[0] as $name){// 必须是大于1个字符且小于5个字符的if(1 < mb_strlen($name,'utf-8') && mb_strlen($name, 'utf-8') < 5){$sub_name = mb_substr($name, 0, 1, 'utf-8');$name_where .= "name like '{$sub_n X什么意思C语言ame}%' or ";}}if(!empty($name_where)){$name_where = substr($name_where, 0, -3);$names_sql = "lect name from surname where {$name_where} order by sort desc";$list = db::getinstance('dbtrade')->getall($names_sql);// 统计有多少种可能性-姓名$result['name_num'] = count($list);if($list) {$name_first = $list[0]['name'];foreach ($names[0] as $name){$len = mb_strlen($name_first, 'utf-8');if (mb_substr($name, 0, $len, 'utf-8') == $name_first){$result['name'] = $name;}}}}}// 去掉详细里面的姓名和电话$result['info'] = str_replace($result['mobile'], '', $result['info']);$result['info'] = str_replace($result['name'], '', $result['info']);$result['info'] = $result['province']['region_name'] . $result['city']['region_name'] . $result['district']['region_name'] . $result['info'];return $this->getcitylevellist($result);}/*** 获取对应城市等级列表**/function getcitylevellist($result){// 获取所有地址递归列表$regions = $this->getregiontreelist();// 获取省份列表- 只有存在值才返回对应列表$province_id = $result['province']['region_id'];if ($province_id) {foreach ($regions as $region){unt($region['childs']);$result['province_list'][] = $region;}}// 获取城市列表- 只有存在值才返回对应列表$city_id = $result['city']['region_id'];if ($city_id) {foreach ($regions[$province_id]['childs'] as $region){unt($region['childs']);$result['city_list'][] = $region;}}// 获取地区列表- 只有存在值才返回对应列表$district_id = $result['district']['region_id'];if ($district_id) {foreach ($regions[$province_id]['childs'][$city_id][中美谈判'childs'] as $region){unt($region['childs']);$result['district_list'][] = $region;}}return $result;}/*** 获取所有地址递归列表**/function getregiontreelist(){// io$file_name = 'regions.json';if(is_file($file_name)){$regions = file_get_contents($file_name);$regions = json_decode($regions, true);} el {$region_sql = "lect region_id,region_name,parent_id from region";$regions = db::getinstance('dbtrade')->getall($region_sql);$regions = $this->arraykey($regions);file_put_contents($file_name, json_encode($regions));}return $regions;}/*** 第一种方法* 根据地址列表递归查找准确地址* @param $address* @return array**/function getaddressarrar($address){// 获取所有地址递归列表$regions = $this->getregiontreelist();// 初始化数据$province = $city = $district = array();// 先查找省份-第一级地区$province = $this->checkaddress($address, $regions);if($province){// 查找城市-第二级地区$city = $this->checkaddress($address, $province['list']);if($city){// 查找地区-第三级地区// 西藏自治区那曲市色尼区辽宁南路西藏公路 第三个参数因为这个地址冲突取消强制$district = $this->checkaddress($address, $city['list']);}}return $this->getaddressinfo($address, $province, $city, $district);}/*** 第二种方法* 地址模糊查找**/function addressvague($address){$res = preg_match_all('/\s{2}[自市区镇县乡岛州]/iu', $address,$arr);if(!$res) return fal;$where = ' where ';foreach ($arr[0] as $value){if(strpos($value, '小区') === fal && strpos($value, '开发区') === fal){$where .= "region_name like '%{$value}' or ";}}$where = substr($where,0,-3);$region_sql = "lect region_id,region_name,parent_id,region_type from region " . $where;$citys = $globals['db']->getall($region_sql);// 匹配所有地址$result = array();foreach ($citys as &$city){// 所有相关联的地区id$city_ids = array();if($city['region_type'] == 2) {$city_ids = array($city['parent_id'], $city['region_id']);// 尝试能不能匹配第三级$region_sql = "lect region_id,region_name,parent_id,region_type,left(region_name,2) as ab_name from region where parent_id='{$city['region_id']}'" ;$areas = $globals['db高中艺考培训']->getall($region_sql);foreach ($areas as $row){if(mb_strpos($address,$row['ab_name'])){$city_ids[] = $row['region_id'];}}} el if($city['region_type'] == 3){$region_sql = "lect parent_id from region where region_id='{$city['parent_id']}'" ;$city['province_id'] = $globals['db']->getone($region_sql);$city_ids = array($city['parent_id'], $city['region_id'], $city['province_id']);}// 查找该单词所有相关的地区记录$where = " where region_id in(" . join(',', $city_ids) . ")";$region_sql = "lect region_id,region_name,parent_id,region_type,left(region_name,2) as ab_name from region " . $where . ' order by region_id asc';$city_list = $globals['db']->getall($region_sql);sort($city_ids);$key = array_pop($city_ids);$result[$key] = $city_list;sort($result);}if($result){list($province, $city, $area) = $result[0];return $this->getaddressinfo($address, $province, $city, $area);}return fal;}/*** 匹配正确的城市地址* @param $address* @param $city_list* @param int $force* @param int $str_len* @return array**/function checkaddress($address, $city_list, $force=fal, $str_len=2){$num = 0;$list = array();$result = array();// 遍历所有可能存在的城市foreach ($city_list as $city_key=>$city){$city_name = mb_substr($city['region_name'], 0, $str_len,'utf-8');// 判断是否存包含当前地址字符$city_arr = explode($city_name, $address);// 如果存在相关字眼,保存该地址的所有子地址if(count($city_arr) >= 2){// 必须名称长度同时达到当前比对长度if(strlen($city['region_name']) < $str_len){continue;}$num ++;$list = $list + $city['childs'];$result[] = array('region_id' => $city['region_id'],'region_name' => $city['region_name'],'list' =>$list,);}}// 如果有多个存在,则加大字符匹配长度if($num > 1 || $force){$region_name1 = $result[0]['region_name'];$region_name2 = $result[1]['region_name'];if(strlen($region_name1) == strlen($region_name2) && strlen($region_name1) == $str_len){$region_id1 = $result[0]['region_id'];$region_id2 = $result[1]['region_id'];$index = $region_id1 > $region_id2 ? 1 : 0;$result = $result[$index];return $result;}return $this->checkaddress($address, $city_list, $force, $str_len+1);} el {$result[0]['list'] = $list;return $result[0];}}/*** 根据原地址返回详细信息* @param $address* @param $province* @param $city* @param $area* @return array**/function getaddressinfo($address, $province, $city, $district){// 查找最后出现的地址 - 截取详细信息$find_str = '';if($province['region_name']){$find_str = $province['region_name'];if($city['region_name']){$find_str = $city['region_name'];if($district['region_name']){$find_str = $district['region_name'];}}}// 截取详细的信息$find_str_len = mb_strlen($find_str,'utf-8');for($i=0; $i<$find_str_len-1; $i++){$substr = mb_substr($find_str,0,$find_str_len - $i, 'utf-8');$end_index = mb_strpos($address, $substr);if ($end_index){$address = mb_substr($address, $end_index + mb_strlen($substr) , mb_strlen($address) - $end_index);}}!empty($find_str) && $find_str = '|\s*' . $find_str;$area['info'] = preg_replace("/\s*|,|,|:|:{$find_str}/i", '', $address);$level = 0;if($district['region_name']){$level = 3;} el if($city['region_name']){$level = 2;} el if ($province['region_name']) {$level = 1;}return array('province' => array('region_id'=>$province['region_id'], 'region_name'=>$province['region_name']),'city'  => array('region_id'=>$city['region_id'], 'region_name'=>$city深圳市房屋租赁['region_name']),'district'  => array('region_id'=>$district['region_id'], 'region_name'=>$district['region_name']),'info'  => $area['info'],'level'  => $level,);}/*** 递归所有地址成无限分类数组* @param $data* @param int $region_id* @return array**/function arraykey($data, $region_id=1){$result = array();foreach ($data as $row){if($region_id == $row['parent_id']){$key = $row['region_id'];$row['childs'] = $this->arraykey($data, $row['region_id']);$result[$key] = $row;}}return $result;}}?>

姓氏surname表(id,姓,优先匹配顺序)

drop table if exists `surname`;create table `surname` (`id` int(11) not null auto_increment,`name` char(10) character t utf8 collate utf8_general_ci null default null,`sort` int(11) null default null,primary key (`id`) using btree,index `name`(`name`) using btree,index `sort`(`sort`) using btree) engine = innodb auto_increment = 481 character t = utf8 collate = utf8_general_ci comment = '姓氏表' row_format = compact;

地址region表()

create table `region` (`region_id` smallint(5) unsigned not null auto_increment,`parent_id` smallint(5) unsigned not null default 0,`region_name` varchar(120) character t utf8 collate utf8_general_ci not null default '',`region_type` tinyint(1) not null default 2,`agency_id` smallint(5) unsigned not null default 0,primary key (`region_id`) using btree,index `parent_id`(`parent_id`) using btree,index `region_type`(`region_type`) using btree,) engine = innodb auto_increment = 3956 avg_row_length = 44 character t = utf8 collate = utf8_general_ci row_format = compact;

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对www.887551.com的支持。如果你想了解更多相关内容请查看下面相关链接

本文发布于:2023-04-06 16:36:04,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/2c22b25aa3b8f41a3fb8525b1cefbfa7.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:PHP智能识别收货地址信息实例.doc

本文 PDF 下载地址:PHP智能识别收货地址信息实例.pdf

下一篇:返回列表
标签:地址   递归   地区   列表
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图