UNPKG

number-reads-cn

Version:

数字中文读法转换工具(电话读法、数值读法、序列读法、金额读法、大写读法)

185 lines (184 loc) 5.73 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.chineseReadToNumber = exports.chineseToNumber = exports.getAllNumberReads = void 0; const digitToChineseMap = { '0': '零', '1': '一', '2': '二', '3': '三', '4': '四', '5': '五', '6': '六', '7': '七', '8': '八', '9': '九', }; const digitToPhoneMap = { '0': '零', '1': '夭', '2': '二', '3': '三', '4': '四', '5': '五', '6': '六', '7': '七', '8': '八', '9': '九', }; const digitToUppercaseMap = { '0': '零', '1': '壹', '2': '贰', '3': '叁', '4': '肆', '5': '伍', '6': '陆', '7': '柒', '8': '捌', '9': '玖', }; /** * 数值中文大写(金额式读法)—— 支持亿以内 */ const numberToChineseValue = (numStr) => { const num = Number(numStr); if (isNaN(num)) return numStr; const digitToChinese = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']; const unit = ['', '十', '百', '千']; const sectionUnit = ['', '万', '亿', '兆']; const toSection = (sectionNum) => { let str = ''; let zero = true; const sectionArr = sectionNum.split('').reverse(); for (let i = 0; i < sectionArr.length; i++) { const n = parseInt(sectionArr[i]); if (n === 0) { if (!zero) { zero = true; str = digitToChinese[0] + str; } } else { zero = false; str = digitToChinese[n] + unit[i] + str; } } return str.replace(/零+$/g, ''); }; const numArr = numStr.split('').reverse().join('').match(/.{1,4}/g) || []; let result = ''; for (let i = 0; i < numArr.length; i++) { const section = toSection(numArr[i].split('').reverse().join('')); if (section !== '') { result = section + sectionUnit[i] + result; } else { if (!result.startsWith('零')) result = '零' + result; } } result = result.replace(/^一十/, '十'); result = result.replace(/零+/g, '零'); result = result.replace(/零+$/g, ''); return result; }; /** * 获取所有中文数字读法 */ const getAllNumberReads = (input) => { const phoneRead = input .split('') .map(char => digitToPhoneMap[char] || char); const phoneSegments = [ phoneRead.slice(0, 3).join(''), phoneRead.slice(3, 7).join(''), phoneRead.slice(7).join(''), ]; const telephone = phoneSegments.filter(s => s).join(' '); const number = numberToChineseValue(input); const currency = number + '元'; const sequence = input .split('') .map(char => digitToChineseMap[char] || char) .join(' '); const upper = input .split('') .map(char => digitToUppercaseMap[char] || char) .join(''); return [ { label: '电话读法', value: telephone }, { label: '数值读法', value: number }, { label: '金额读法', value: currency }, { label: '序列读法', value: sequence }, { label: '大写读法', value: upper }, ]; }; exports.getAllNumberReads = getAllNumberReads; /** * 将中文数字读法(如:一百八十六)反向转为数字(如:186) * 暂只支持简体数字读法,不支持金额/大写/序列等 */ const chineseToNumber = (chinese) => { const charToDigit = { '零': 0, '一': 1, '二': 2, '三': 3, '四': 4, '五': 5, '六': 6, '七': 7, '八': 8, '九': 9 }; const unitMap = { '十': 10, '百': 100, '千': 1000, '万': 10000, '亿': 100000000 }; let result = 0; let section = 0; let number = 0; let unit = 1; for (let i = chinese.length - 1; i >= 0; i--) { const char = chinese[i]; if (char in charToDigit) { number = charToDigit[char]; if (unit > 1) { section += number * unit; unit = 1; } else { section += number; } } else if (char in unitMap) { unit = unitMap[char]; if (unit >= 10000) { result += section * unit; section = 0; } } else { // 忽略非数字字符 } } result += section; return isNaN(result) ? null : result; }; exports.chineseToNumber = chineseToNumber; /** * 支持 getAllNumberReads 返回的所有读法反向转为数字 */ const chineseReadToNumber = (read) => { // 去除空格和单位 const cleanRead = read.replace(/[元\s]/g, ''); // 如果是序列或电话读法(逐个数字中文) if (/^[零一二三四五六七八九夭]+$/.test(cleanRead)) { const map = { '夭': '1', '零': '0', '一': '1', '二': '2', '三': '3', '四': '4', '五': '5', '六': '6', '七': '7', '八': '8', '九': '9' }; return Number(cleanRead.split('').map(c => map[c] || '').join('')) || null; } // 如果是大写读法(壹贰叁) if (/^[壹贰叁肆伍陆柒捌玖零]+$/.test(cleanRead)) { const map = { '壹': '1', '贰': '2', '叁': '3', '肆': '4', '伍': '5', '陆': '6', '柒': '7', '捌': '8', '玖': '9', '零': '0' }; return Number(cleanRead.split('').map(c => map[c] || '').join('')) || null; } // 否则用中文数值解析(如 一百八十六) return (0, exports.chineseToNumber)(cleanRead); }; exports.chineseReadToNumber = chineseReadToNumber;