/* 这里的金额 只到千万 不含亿元转换 */
/** 如果有亿元 算法和以下一样 加几步就是 */
/**
想法: 把金额拆分三个数组分别计算
1. 以万结束为一个
2. 以元结束为一个
3. 小数 角分 为一个
万字读法:几千几百几十几万 遇到零只会读一个零 例如 : 几千零几万 这样子
万到元中间的读法也是: 几千几百几十几元
角分略过;
中心算法:
(n*1000 + n*100 + n*10 + n*1)*10000 + n*1000 + n*100 + n*10 + n*1;
因为中间可能存在两个数字连读 所以遇到时 我们把单位赋值为1 则不会影响
*/
以下为ts代码:
/** 万元前面金额 */
let numInit = 0;
/** 角分小数 */
let numfloat = '';
/** 全部金额 */
let numAll: any;
/** 千元金额 */
let letter = 0;
/** 通过map方法找到对应的金额 */
const numMap = new Map([
['零', 0], ['壹', 1], ['贰', 2], ['叁', 3], ['肆', 4], ['伍', 5], ['陆', 6], ['柒', 7], ['捌', 8], ['玖', 9]
]);
/** 赋值单位*/
const integerMap = new Map<string, string>([
['', ''],
['拾', '10'],
['佰', '100'],
['仟', '1000'],
['万', '10000'],
]);
/** 以小数分成两组数据 */
num = ('' + num).split(/圆|元/);
/*定义第一个数组和第二个数组,
integer :整数
decimal :小数点后面保持两位 角分为止;
another: 在‘万’元以上字 在intergerMap找不到的时候 ;
single: 在‘千’元以内字 在intergerMap找不到的时候
*/
let integer = num[0],
decimal = num[1] ? num[1].substr(0, 4) : [], another, single;
/** 把元之前的数据以万字拆分 */
integer = integer.split(/万/);
/* if:如果金额大于万元以上; else: 千元以内*/
if (integer.length > 1) {
/* 万元以上数据循环 */
for (let i = 0; i < integer[0].length; i++) {
if (numMap.get(integer[0][i])) { /* 如果能识别出来数字0-9 */
if (integerMap.get(integer[0][i + 1])) { /* if:如果能识别出来单位 把单位赋值; else: 如果识别不出 则为1*/
another = integerMap.get(integer[0][i + 1]);
} else {
another = 1;
}
/** 算法应该是: 数字*单位 + 数字*单位....... 当一个数字后面没有跟单位时 单位则为1 */
numInit = +numInit + (+numMap.get(integer[0][i]) * +(+another));
}
}
/* 千元以上数据循环 和上面算法一样 */
for (let i = 0; i < integer[1].length; i++) {
/* if (numMap.get(integer[0][i])) {
this.numInit = +this.numInit + (+numMap.get(integer[0][i]));
} */
if (numMap.get(integer[1][i])) {
if (integerMap.get(integer[1][i + 1])) {
single = integerMap.get(integer[1][i + 1]);
} else {
single = 1;
}
letter = +letter + (+numMap.get(integer[1][i]) * +(+single));
}
}
} else {
for (let i = 0; i < integer[0].length; i++) {
/* if (numMap.get(integer[0][i])) {
this.numInit = +this.numInit + (+numMap.get(integer[0][i]));
} */
if (numMap.get(integer[0][i])) {
if (integerMap.get(integer[0][i + 1])) {
single = integerMap.get(integer[0][i + 1]);
} else {
single = 1;
}
letter = +letter + (+numMap.get(integer[0][i]) * +(+single));
}
}
}
/** 算出来的万元*10000 + 千元 应该就是整数的金额*/
numAll = numInit * 10000 + letter;
/** 小数角分的算法*/
for (let i = 0; i < decimal.length; i++) {
if (numMap.get(decimal[i])) {
// console.log();
numfloat = numfloat + numMap.get(decimal[i]);
}
}
/** 如果存在小数 则加上 没有直接为上面的numAll */
if (numfloat) {
numAll = numAll + '.' + numfloat;
}
方法二 用正则匹配 亿 万 元 (可以匹配到亿元)
/** 大写表 */
private _chineseNumber = new Map<string, number>([
['壹', 1], ['贰', 2], ['叁', 3], ['肆', 4], ['伍', 5], ['陆', 6], ['柒', 7], ['捌', 8], ['玖', 9]
]);
/** 金额单位 */
private _chineseUnit = new Map<string, number>([
['亿', 100000000], ['万', 10000], ['仟', 1000], ['佰', 100], ['拾', 10], ['元', 1], ['角', 0.1], ['分', 0.01]
]);
constructor() {
}
/** 中文大写数字转换 */
public chineseToNumber = (chinese: string): number => {
let result: any = 0;
/** 匹配单位 */
const groupReg = /([零|壹|贰|叁|肆|伍|陆|柒|捌|玖|仟|佰|拾]+[亿|万|元|角|分])/g;
/** 匹配单位数字 */
const numberReg = /([壹|贰|叁|肆|伍|陆|柒|捌|玖][仟|佰|拾]?)/g;
/** 分组:[xx亿,xx万,xx元,xx角,xx分] */
const groupResult: Array<string> = Array.isArray(chinese.match(groupReg)) ? chinese.match(groupReg) : [];
groupResult.forEach(strUnits => {
/** 分组单位:亿,万,元,角,分 */
const groupUnit: number = this._chineseUnit.get(strUnits.substr(-1, 1));
const numberResult: Array<string> = Array.isArray(strUnits.match(numberReg)) ? strUnits.match(numberReg) : [];
/** 组 匹配数字:[六百,二十,三] */
numberResult.forEach((strUnit) => {
const number: number = this._chineseNumber.get(strUnit.substr(0, 1));
const unit: number = this._chineseUnit.get(strUnit.substr(1, 2)) || 1;
/** 结果累加 */
result += number * unit * groupUnit;
});
});
return result;```