大家好,我是Echa。 今天给大家分享非常实用的收货信息智能识别工具,该工具使用广泛,比如小程序,H5,App等等,大大提高用户体验和工作效率。但是市面上大部分都是按照API调用平次来收费的,总体来说比较贵。目前推荐这个是免费的,智能匹配率大概在85作用,希望大家喜欢。创作不易,喜欢的老铁们加个关注,点个赞,后面会持续更新干货,速速收藏,谢谢! 源码地址:https:gitee。comJCfengjsutiltreemainaddressauto 效果图: 核心代码:收件人信息自动识别param{String}autovalue输入的信息returns{ReturnInfo}functionaddressauto(autovalue){储存分割后的数据type{String〔〕}letsplitres〔autovalue〕支持的分割符type{string〔〕}letsplitters〔,,,,,r,〕按不同的分隔符依次分割for(letsplitterofsplitters){letsplitres1〔〕for(letsplitresitemofsplitres){splitres1。push(。。。splitresitem。split(splitter))}splitressplitres1}类型标记后面会对每个分割后的部分进行类型检测letTYPEMOBILE10手机letTYPENAME11名字letTYPEADDRPROVINCE12地址省份部分letTYPEADDRCITY13地址城市部分letTYPEADDRCOUNTY14地址区县部分letTYPEADDRDETAIL15地址详细地址部分地址中可写可不写的部分letDISPENSIBLEPROVINCES〔省,市,自治区〕letDISPENSIBLECITYS〔市,地区,区,盟,自治州〕letDISPENSIBLECOUNTYS〔林区,族区,区,自治县,县,市,自治旗,旗〕储存地区信息的结构typedef{Object}AreaInfoproperty{String}code地区编码property{String}name地区名称property{String}nameexceptdispensible除了dispensible部分后的地区名称property{Number}similarity匹配nameexceptdispensible时的相似度地区数据处理函数param{Object。String,String}data地区数据param{Array。String}dispensiblelist可忽略的内容returns{Array。}}letareadataprocessingfunction(data,dispensiblelist){returnObject。entries(data)。map(entry{letitem{code:entry〔0〕,name:entry〔1〕,nameexceptdispensible:entry〔1〕,similarity:1,}for(letdispensibleitemofdispensiblelist){if(item。name。endsWith(dispensibleitem)item。name。lengthdispensibleitem。length2){item。nameexceptdispensibleitem。name。substring(0,item。name。lengthdispensibleitem。length)item。similarityitem。nameexceptdispensible。lengthitem。name。lengthbreak}}returnitem})}letprovincesareadataprocessing(areaList。provincelist,DISPENSIBLEPROVINCES)储存省份信息的数组letcitysareadataprocessing(areaList。citylist,DISPENSIBLECITYS)储存省份信息的数组letcountysareadataprocessing(areaList。countylist,DISPENSIBLECOUNTYS)储存省份信息的数组匹配到的信息的结构typedef{Object}ResInfoproperty{String}code地区编码property{String}name地区名称property{Number}similarity相似度(完全匹配时为1)property{Number}splitresindex对应的splitres数组中的数据的索引property{String}〔captureprovince〕捕获的省份内容,此字段只在省份信息内存在property{String}〔capturecity〕捕获的城市内容,此字段只在城市信息内存在property{String}〔capturecounty〕捕获的区县内容,此字段只在区县信息内存在property{Number}〔maxcitysplitresindex〕最大相似度的城市对应的splitres数组中的数据的索引,此字段只在最终结果中存在property{Number}〔maxcityresInfoindex〕最大相似度的城市对应的cityresInfolist数组中的数据的索引,此字段只在最终结果中存在property{Number}〔maxprovincesplitresindex〕最大相似度的省份对应的splitres数组中的数据的索引,此字段只在最终结果中存在property{Number}〔maxprovinceresInfoindex〕最大相似度的省份对应的provinceresInfolist数组中的数据的索引,此字段只在最终结果中存在储存匹配到的省份信息type{ResInfo〔〕}letprovinceresInfolist〔〕储存匹配到的城市信息type{ResInfo〔〕}letcityresInfolist〔〕储存匹配到的区县信息type{ResInfo〔〕}letcountyresInfolist〔〕分割后的数据的扩展结构typedef{Object}SplitResExproperty{String}value原始splitres数组内对应的元素property{Number}type类型标记对splitres数组的数据进行处理后的拓展数据type{SplitResEx〔〕}letsplitresexsplitres。filter(splitresitemsplitresitem!)。map(splitresitem{return{value:splitresitem,type:0,}})用于匹配11位手机号的正则表达式letregexpmobilenewRegExp(〔09〕{11},gmu)储存手机的识别结果letmobile储存splitresex数组内识别到手机的元素的索引letmobilesplitresindex1开始识别,遍历splitresexfor(leti0;isplitresex。length;i){letsplitresitemsplitresex〔i〕当前遍历元素识别到手机(如果有多个,只储存最后一个)if(regexpmobile。test(splitresitem。value)){splitresitem。typeTYPEMOBILE标记类型mobilesplitresitem。value储存识别结果mobilesplitresindexi储存对应索引}对每个splitresex元素遍历识别所有的省份、城市、区县构建〔省份、城市、区县〕遍历结构letloopdata〔{data:provinces,type:TYPEADDRPROVINCE,resInfolist:provinceresInfolist,typename:province},{data:citys,type:TYPEADDRCITY,resInfolist:cityresInfolist,typename:city},{data:countys,type:TYPEADDRCOUNTY,resInfolist:countyresInfolist,typename:county},〕遍历〔省份、城市、区县〕for(letj0;j3;j){遍历(省份)或(城市)或(区县)for(letitemofloopdata〔j〕。data){letsimilarityundefined相似度letcapturevalueundefined储存捕获到的名称完整匹配某个(省份)或(城市)或(区县)的名称if(splitresitem。value。search(item。name)!1){similarity1相似度为1capturevalueitem。name储存完整名称}非完整匹配某个(省份)或(城市)或(区县)的名称elseif(splitresitem。value。search(item。nameexceptdispensible)!1){similarityitem。similarity储存相似度(前面已计算)capturevalueitem。nameexceptdispensible储存省略后的名称}成功匹配,储存信息if(similarity!undefined){loopdata〔j〕。resInfolist。push({code:item。code,name:item。name,similarity:similarity,splitresindex:i,〔capture{loopdata〔j〕。typename}〕:capturevalue})}}}}由区县的匹配结果决定地址信息最终是否匹配成功只要区县匹配成功,不论城市和省份是否匹配成功,最终都将按匹配成功处理下面的处理主要是针对匹配到多个区县的情况,最终按叠加的相似度决定匹配结果因为该步骤主要是为了消除误判的区县,所以区县所属的城市和省份被匹配时,权重分别是10倍和100倍if(countyresInfolist。length1){遍历区县的匹配结果for(leti0;icountyresInfolist。length;i){letcountyresInfoitemcountyresInfolist〔i〕本次遍历的区县元素letaddsimilarity0最后要叠加到区县结果内的相似度遍历城市的匹配结果for(letj0;jcityresInfolist。length;j){若匹配成功的区县其所属的城市同时也匹配成功,则记录其相似度if(cityresInfolist〔j〕。code。substring(0,4)countyresInfoitem。code。substring(0,4)){被匹配的区县所属的城市可能会匹配到多个,所以要找出其中相似度最大的if(cityresInfolist〔j〕。similarityaddsimilarity){addsimilaritycityresInfolist〔j〕。similarity}}}countyresInfoitem。similarityaddsimilarity10在城市的相似度的基础上乘10遍历省份的匹配结果(同上)addsimilarity0for(letj0;jprovinceresInfolist。length;j){if(provinceresInfolist〔j〕。code。substring(0,2)countyresInfoitem。code。substring(0,2)){if(provinceresInfolist〔j〕。similarityaddsimilarity){addsimilarityprovinceresInfolist〔j〕。similarity}}}countyresInfoitem。similarityaddsimilarity100在省份的相似度的基础上乘10}按叠加后的相似度对区县的匹配结果进行排序,从大到小countyresInfolist。sort((item0,item1)item1。similarityitem0。similarity)排序后的区县匹配结果中的第一个元素视作最终匹配元素letmatchingcountycountyresInfolist〔0〕在对应的splitresex数组内的数据上加上区县地址匹配标记splitresex〔matchingcounty。splitresindex〕。typeTYPEADDRCOUNTY在城市匹配结果中寻找最终匹配的区县所属的城市letmaxsimilarity0临时变量,记录当前已遍历的匹配城市中相似度最大的letmaxresInfoindex1相似度最大的城市在cityresInfolist数组中对应的索引for(leti0;icityresInfolist。length;i){if(cityresInfolist〔i〕。code。substring(0,4)matchingcounty。code。substring(0,4)){if(cityresInfolist〔i〕。similaritymaxsimilarity){maxsimilaritycityresInfolist〔i〕。similaritymaxresInfoindexi}}}若寻找到相应的匹配城市,则储存和设置对应的信息if(maxresInfoindex!1){matchingcounty。maxcitysplitresindexcityresInfolist〔maxresInfoindex〕。splitresindexmatchingcounty。maxcityresInfoindexmaxresInfoindexsplitresex〔cityresInfolist〔maxresInfoindex〕。splitresindex〕。typeTYPEADDRCITY}在省份匹配结果中寻找最终匹配的区县所属的省份,同上maxsimilarity0maxresInfoindex1for(leti0;iprovinceresInfolist。length;i){if(provinceresInfolist〔i〕。code。substring(0,2)matchingcounty。code。substring(0,2)){if(provinceresInfolist〔i〕。similaritymaxsimilarity){maxsimilarityprovinceresInfolist〔i〕。similaritymaxresInfoindexi}}}if(maxresInfoindex!1){matchingcounty。maxprovincesplitresindexprovinceresInfolist〔maxresInfoindex〕。splitresindexmatchingcounty。maxprovinceresInfoindexmaxresInfoindexsplitresex〔provinceresInfolist〔maxresInfoindex〕。splitresindex〕。typeTYPEADDRPROVINCE}}储存名字的识别结果letnamesplitresex数组中还未匹配到任何类型的元素letsplitrestypeequal0〔〕遍历splitresex数组,寻找还未匹配到任何类型的元素for(leti0;isplitresex。length;i){if(splitresex〔i〕。type0){splitrestypeequal0。push({splitresitem:splitresex〔i〕,index:i})}}按内容的长度排序,从小到大splitrestypeequal0。sort((item0,item1)item0。splitresitem。value。lengthitem1。splitresitem。value。length)遍历排序后的splitrestypeequal0数组(splitrestypeequal0数组中除了可能存在名字外,还可能存在详细地址)规则1:名字不会被除手机外的其他信息包裹在中间,既除手机外,名字应该在两端规则2:名字不会比详细地址长for(leti0;isplitrestypeequal0。length;i){letitemsplitrestypeequal0〔i〕。splitresitem对应的splitresitem数组的元素letindexsplitrestypeequal0〔i〕。index对应的splitresitem数组的元素的索引letaccessindexs;储存特定情况下,名字所有可能出现的位置(名字应该在两端)若未匹配到手机,则名字应该在两端,否则,名字应该在除了手机所在位置后的两端if(mobilesplitresindex0){accessindexs〔1,splitresex。length1〕}elseif(mobilesplitresindexsplitresex。length1){accessindexs〔0,splitresex。length2〕}else{accessindexs〔0,splitresex。length1〕}匹配if(accessindexs。indexOf(index)!1){若splitrestypeequal0内不止一个元素,说明splitrestypeequal0内存在详细地址部分if(splitrestypeequal0。length1){letaddlength0储存除本元素外的其他元素的内容长度的累加值累加其他部分for(letj0;ji;j){addlengthsplitrestypeequal0〔j〕。splitresitem。value。length}for(letji1;jsplitrestypeequal0。length;j){addlengthsplitrestypeequal0〔j〕。splitresitem。value。length}若本元素长度小于其他元素的长度累加值,则判定本元素为名字if(item。value。lengthaddlength){item。typeTYPENAMEnameitem。valuebreak}}若splitrestypeequal0内只有一个元素,则判定本元素为名字else{item。typeTYPENAMEnameitem。valuebreak}}}letprovince储存省份的识别结果letcity储存城市的识别结果letcounty储存区县的识别结果letcode储存地区编码的识别结果letdetail储存详细地址的识别结果若有识别到区县地址if(countyresInfolist。length0){letmatchingcountycountyresInfolist〔0〕最终匹配元素letdetailjoinindexlist〔〕储存详细地址的各个部分对应的splitresex数组元素的索引若有匹配到的省份if(matchingcounty。hasOwnProperty(maxprovincesplitresindex)){detailjoinindexlist。push(matchingcounty。maxprovincesplitresindex)provinceprovinceresInfolist〔matchingcounty。maxprovinceresInfoindex〕。name}else{provinceareaList。provincelist〔matchingcounty。code。substring(0,2)0000〕}若有匹配到的城市if(matchingcounty。hasOwnProperty(maxcitysplitresindex)){检测是否与匹配到的省份对应的splitresex数组元素的索引重复,不重复才添加if(detailjoinindexlist。indexOf(matchingcounty。maxcitysplitresindex)1){detailjoinindexlist。push(matchingcounty。maxcitysplitresindex)}citycityresInfolist〔matchingcounty。maxcityresInfoindex〕。name}else{cityareaList。citylist〔matchingcounty。code。substring(0,4)00〕}检测是否与匹配到的省份及城市对应的splitresex数组元素的索引重复,不重复才添加if(detailjoinindexlist。indexOf(matchingcounty。splitresindex)1){detailjoinindexlist。push(matchingcounty。splitresindex)}countymatchingcounty。namecodematchingcounty。code将其余未匹配到任何类型的元素判定为详细地址部分,添加其对应的splitresex数组元素的索引到detailjoinindexlist数组for(leti0;isplitresex。length;i){if(splitresex〔i〕。type0){detailjoinindexlist。push(i)}}拼接detailjoinindexlist数组内所有元素对应的splitresex数组元素的内容detaildetailjoinindexlist。map(isplitresex〔i〕。value)。join()去除省份信息if(matchingcounty。hasOwnProperty(maxprovinceresInfoindex)){detaildetail。replace(provinceresInfolist〔matchingcounty。maxprovinceresInfoindex〕。captureprovince,)}去除城市信息if(matchingcounty。hasOwnProperty(maxcityresInfoindex)){detaildetail。replace(cityresInfolist〔matchingcounty。maxcityresInfoindex〕。capturecity,)}去除区县信息detaildetail。replace(matchingcounty。capturecounty,)}return{name:name,tel:mobile,province:province,city:city,county:county,areaCode:code,addressDetail:detail,}}