JS寄快遞地址智能解析的實現(xiàn)代碼
去年做了些前端內(nèi)容,最近在整理一些稍微有點用的內(nèi)容,比如智能解析地址,用戶只要輸入:張三1351111111江蘇省揚州市廣陵區(qū)XX小區(qū)X樓xxx室,就能解析出姓名、電話、省市區(qū)、地址信息了。是不是很方便?
項目地址暫時沒有放,大家可以關(guān)注我的個人碼云地址https://gitee.com/w9
純JavaScript,無需Jquery,輕量級的JS包。可參考以下代碼:
let defaultData = [];
const mCity = {};
const mArea = {};
/**
* 處理原始地址數(shù)據(jù)轉(zhuǎn)換成專用數(shù)據(jù)
* @param list 原始數(shù)據(jù)
* @param init 是否初始化 如傳空 已轉(zhuǎn)換過不會再次轉(zhuǎn)換
* @returns {boolean}
*/
function parseArea(list, init) {
if (!init && defaultData.length) {
return true;
}
defaultData = list;
defaultData.forEach(province => {
if (province.city) {
province.city.forEach(city => {
if (city.name !== '其他') {
if (!mCity[city.name]) {
mCity[city.name] = [];
}
mCity[city.name].push({
p: province.name,
c: city.name,
a: city.area || []
});
}
if (city.area) {
city.area.forEach(area => {
if (area !== '其他') {
if (!mArea[area]) {
mArea[area] = [];
}
mArea[area].push({
p: province.name,
c: city.name
})
}
})
}
})
}
});
}
/**
* 解析郵編
* @param
* @returns <array>
*/
function zipCodeFormat() {
let list = []
zipCode.forEach((el) => {
if (el.child) {
el.child.forEach((event) => {
if (event.child) {
event.child.forEach(element => {
list.push(element.zipcode)
})
}
})
}
})
return list;
}
//專用數(shù)據(jù)處理
let zipCodeList = zipCodeFormat();//郵編
parseArea(areaList);//地址
/**
* 解析
* @param address 任意地址字符串
* @returns {{name: string, mobile: string, detail: string, zip_code: string, phone: string}}
*/
function parse(address) {
address = address || '';
const parse = {
name: '',
mobile: '',
detail: '',
zip_code: '',
phone: ''
};
//去除空格...
address = address.replace(/\r\n/g, ' ').replace(/\n/g, ' ').replace(/\t/g, ' ');
address = address.replace(/\s+/g, "");
//自定義去除關(guān)鍵字,可自行添加
const search = ['地址', '收貨地址', '收貨人', '收件人', '收貨', '郵編', '電話', ':', ':', ';', ';', ',', ',', '。', ];
search.forEach(str => {
address = address.replace(new RegExp(str, 'g'), ' ')
});
//多個空格replace為一個
address = address.replace(/ {2,}/g, ' ');
//整理電話格式
address = address.replace(/(\d{3})-(\d{4})-(\d{4})/g, '$1$2$3');
address = address.replace(/(\d{3}) (\d{4}) (\d{4})/g, '$1$2$3');
const mobileReg = /(86-[1][0-9]{10})|(86[1][0-9]{10})|([1][0-9]{10})/g;
const mobile = mobileReg.exec(address);
if (mobile) {
parse.mobile = mobile[0];
address = address.replace(mobile[0], ' ')
}
//電話
const phoneReg = /(([0-9]{3,4}-)[0-9]{7,8})|([0-9]{12})|([0-9]{11})|([0-9]{10})|([0-9]{9})|([0-9]{8})|([0-9]{7})/g;
const phone = phoneReg.exec(address);
if (phone) {
parse.phone = phone[0];
address = address.replace(phone[0], ' ')
}
//郵編(加入門牌號;考慮到重復(fù)郵編問題;去除之前簡單的六位數(shù)字校驗)
for (let index = 0; index < zipCodeList.length; index++) {
if (address.indexOf(zipCodeList[index]) != -1) {
let num = address.indexOf(zipCodeList[index]);
let code = address.slice(num, num + 6);
parse.zip_code = code;
address = address.replace(code, '')
}
}
/* 廢棄
const zipReg = /([0-9]{6})/g;
const zip = zipReg.exec(address);
if (zip) {
parse.zip_code = zip[0];
address = address.replace(zip[0], '')
}
*/
address = address.replace(/ {2,}/, ' ');
//console.log(address)
let detail = detail_parse_forward(address.trim());
if (!detail.city) {
detail = detail_parse(address.trim());
if (detail.area && !detail.city) {
detail = detail_parse(address.trim(), {
ignoreArea: true
});
console.log('smart_parse->ignoreArea(忽略區(qū))');
} else {
// console.log('smart_parse');
}
//這個待完善
const list = address.replace(detail.province, '').replace(detail.city, '').replace(detail.area, '').split(' ').filter(str => str);
//詳細住址劃分關(guān)鍵字
//注意:只需要填寫關(guān)鍵字最后一位即可:比如單元填寫元即可!
const address_detail_list = ['室', '樓', '元', '號', '幢', '門', '戶'];
if (list.length > 1) {
list.forEach(str => {
if (!parse.name || str && str.length < parse.name.length) {
parse.name = str.trim()
}
});
if (parse.name) {
detail.addr = detail.addr.replace(parse.name, '').trim()
}
} else {//若名字寫在詳細地址后面,根據(jù)address_detail_list進行分割;
let key = [];
address_detail_list.forEach((el) => {
key.push(detail.addr.indexOf(el))
})
var max = key.sort(function (a, b) {
return b - a;
})[0];
if (max != -1) {
let addrBuild = detail.addr.slice(0, max + 1);
let addrNum = detail.addr.replace(addrBuild, '').replace(/[^0-9]+/g, '');
let userName = detail.addr.replace(addrBuild + addrNum, '')
detail.addr = addrBuild + addrNum
parse.name = userName
}
}
} else {
if (detail.name) {
parse.name = detail.name
} else {
const list = detail.addr.split(' ').filter(str => str);
if (list.length > 1) {
parse.name = list[list.length - 1]
}
if (parse.name) {
detail.addr = detail.addr.replace(parse.name, '').trim()
}
}
}
parse.province = detail.province;
parse.city = detail.city;
parse.area = detail.area;
parse.addr = detail.addr;
parse.result = detail.result;
return parse;
}
/**
* 正向解析模式
* 從前到后按 province city addr 逐級篩選
* 有city的值即可說明解析成功
* 此模式對地址順序有要求
* @param address
* @returns {{province: string, city: string, area: string, addr: string}}
*/
function detail_parse_forward(address) {
const parse = {
province: '',
city: '',
area: '',
addr: '',
name: '',
};
const provinceKey = ['特別行政區(qū)', '古自治區(qū)', '維吾爾自治區(qū)', '壯族自治區(qū)', '回族自治區(qū)', '自治區(qū)', '省省直轄', '省', '市'];
const cityKey = ['布依族苗族自治州', '苗族侗族自治州', '自治州', '州', '市', '縣'];
for (let i in defaultData) {
const province = defaultData[i];
let index = address.indexOf(province.name);
if (index > -1) {
if (index > 0) {
//省份不是在第一位,在省份之前的字段識別為名稱
parse.name = address.substr(0, index).trim();
}
parse.province = province.name;
address = address.substr(index + province.name.length);
for (let k in provinceKey) {
if (address.indexOf(provinceKey[k]) === 0) {
address = address.substr(provinceKey[k].length);
}
}
for (let j in province.city) {
const city = province.city[j];
index = address.indexOf(city.name);
if (index > -1 && index < 3) {
parse.city = city.name;
address = address.substr(index + parse.city.length);
for (let k in cityKey) {
if (address.indexOf(cityKey[k]) === 0) {
address = address.substr(cityKey[k].length);
}
}
if (city.area) {
for (let k in city.area) {
const area = city.area[k];
index = address.indexOf(area);
if (index > -1 && index < 3) {
parse.area = area;
address = address.substr(index + parse.area.length);
break;
}
}
}
break;
}
}
parse.addr = address.trim();
break;
}
}
return parse;
}
/**
* 逆向解析 從后【縣,區(qū),旗】往前解析
* 有地區(qū)就能大概返回地址了
* @param address
* @param ignoreArea 是否忽視區(qū) 因為地址中含有區(qū)容易導(dǎo)致匹配錯誤 例:山東省蓬萊市黃?;▓@東區(qū)西門寶威學(xué)堂 曲榮聲收15753572456
* @returns {{province: string, city: string, area: string, name: string, _area: string, addr: string}}
*/
function detail_parse(address, {
ignoreArea = false
} = {}) {
const parse = {
province: '',
city: '',
area: '',
name: '',
_area: '',
addr: '',
};
let areaIndex = -1,
cityIndex = -1;
address = address.replace(' ', ' ');
if (!ignoreArea && address.indexOf('縣') > -1 || !ignoreArea && address.indexOf('區(qū)') > -1 || !ignoreArea && address.indexOf('旗') > -1) {
if (address.indexOf('旗') > -1) {
areaIndex = address.indexOf('旗');
parse.area = address.substr(areaIndex - 1, 2);
}
if (address.indexOf('區(qū)') > -1) {
areaIndex = address.indexOf('區(qū)');
if (address.lastIndexOf('市', areaIndex) > -1) {
cityIndex = address.lastIndexOf('市', areaIndex);
parse.area = address.substr(cityIndex + 1, areaIndex - cityIndex);
} else {
parse.area = address.substr(areaIndex - 2, 3);
}
}
if (address.indexOf('縣') > -1) {
areaIndex = address.lastIndexOf('縣');
if (address.lastIndexOf('市', areaIndex) > -1) {
cityIndex = address.lastIndexOf('市', areaIndex);
parse.area = address.substr(cityIndex + 1, areaIndex - cityIndex);
} else {
parse.area = address.substr(areaIndex - 2, 3);
}
}
parse.addr = address.substr(areaIndex + 1);
} else {
if (address.indexOf('市') > -1) {
areaIndex = address.indexOf('市');
parse.area = address.substr(areaIndex - 2, 3);
parse.addr = address.substr(areaIndex + 1);
} else {
parse.addr = address
}
}
if (address.indexOf('市') > -1 || address.indexOf('盟') > -1 || address.indexOf('州') > -1) {
if (address.indexOf('市') > -1) {
parse._area = address.substr(address.indexOf('市') - 2, 2);
}
if (address.indexOf('盟') > -1 && !mCity[parse._area]) {
parse._area = address.substr(address.indexOf('盟') - 2, 2);
}
if (address.indexOf('州') > -1 && !mCity[parse._area]) {
parse._area = address.substr(address.indexOf('州') - 2, 2);
}
}
parse.area = parse.area.trim();
if (parse.area && mArea[parse.area]) {
if (mArea[parse.area].length === 1) {
parse.province = mArea[parse.area][0].p;
parse.city = mArea[parse.area][0].c
} else {
parse._area = parse._area.trim();
const addr = address.substr(0, areaIndex);
const d = mArea[parse.area].find(item => {
return item.p.indexOf(addr) > -1 || item.c === parse._area;
});
if (d) {
parse.province = d.p;
parse.city = d.c
} else {
parse.result = mArea[parse.area];
}
}
} else {
if (parse._area) {
const city = mCity[parse._area];
if (city) {
parse.province = city[0].p;
parse.city = city[0].c;
parse.addr = address.substr(address.indexOf(parse.city) + parse.city.length + 1);
parse.area = '';
for (let i in city[0].a) {
if (parse.addr.indexOf(city[0].a[i]) === 0) {
parse.area = city[0].a[i];
parse.addr = parse.addr.replace(city[0].a[i], '');
break;
}
}
}
} else {
parse.area = '';
}
}
parse.addr = parse.addr.trim();
return parse
}
/*export {parseArea}
export default parse;*/
下面介紹部分使用實例:
Html
<textarea class="weui-textarea sj_textarea" onchange="smart_parse2()" placeholder="[智能填寫] 例如:張三1351111111江蘇省揚州市廣陵區(qū)XX小區(qū)X樓xxx室" rows="2"></textarea>
JavaScript
//智能識別地址
function smart_parse2() {
var value = $('.sj_textarea').val();
console.log(parse(value));//這里可以看一下解析出來的內(nèi)容
var html = '';
for (var key in parse(value)) {
if (parse(value)[key]) {
html += `<p>` + key + `:` + parse(value)[key] + `</p>`
}
} //把解析的內(nèi)容在賦值到頁面元素中(這兒業(yè)務(wù)使用的Jq,實際上不需要)
$('#sj_name').val(parse(value).name);
$('#sj_phone').val(parse(value).phone);
$('#city-picker2').val(parse(value).province + ' ' + parse(value).city + ' ' + parse(value).area);
$('#sj_addr').val(parse(value).addr);
}
使用起來非常方便,容錯率也高。
到此這篇關(guān)于JS寄快遞地址智能解析的文章就介紹到這了,更多相關(guān)js 寄快遞內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何使用require.context實現(xiàn)優(yōu)雅的預(yù)加載
這篇文章主要介紹了使用require.context實現(xiàn)優(yōu)雅的預(yù)加載?,需要的朋友可以參考下2023-05-05

