├── .gitattributes ├── .gitignore ├── .nojekyll ├── .nvmrc ├── .travis.yml ├── README.md ├── bower.json ├── cn.js ├── demo └── index.html ├── dist ├── nzh.cn.js ├── nzh.cn.min.js ├── nzh.hk.js ├── nzh.hk.min.js ├── nzh.js └── nzh.min.js ├── docs ├── .nojekyll ├── _sidebar.md ├── demo.md └── index.html ├── gulpfile.js ├── hk.js ├── index.html ├── lib ├── nzh.cn.js ├── nzh.hk.js └── nzh.js ├── nzh.d.ts ├── nzh.js ├── package.json ├── src ├── autoGet.js ├── index.js ├── langs │ ├── cn_b.js │ ├── cn_s.js │ ├── hk_b.js │ └── hk_s.js └── utils.js └── test ├── browser ├── amd.html ├── cmd.html ├── index.html └── test.html ├── temp.js ├── testData.js └── test_mocha.js /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # ========================= 18 | # Operating System Files 19 | # ========================= 20 | 21 | # OSX 22 | # ========================= 23 | 24 | .DS_Store 25 | .AppleDouble 26 | .LSOverride 27 | 28 | # Icon must ends with two \r. 29 | Icon 30 | 31 | 32 | # Thumbnails 33 | ._* 34 | 35 | # Files that might appear on external disk 36 | .Spotlight-V100 37 | .Trashes 38 | 39 | node_modules 40 | 41 | test/browser/tests.js -------------------------------------------------------------------------------- /.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnwhy/nzh/71f536cd4ef1cb37bc68cdc3a45b3ea61fcc7153/.nojekyll -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 10 -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | sudo: false 3 | node_js: 4 | - "6" 5 | - "7" 6 | - "8" 7 | - "9" 8 | - "10" 9 | before_script: 10 | - npm install -g gulp 11 | # - npm install -g istanbul 12 | script: gulp test-server 13 | #Run test script, depending on istanbul install 14 | # - "test -n $(npm -ps ls istanbul) || npm test" 15 | # - "test -z $(npm -ps ls istanbul) || npm run-script test-travis" 16 | 17 | #after_script: 18 | # - "test -e ./coverage/lcov.info && npm install coveralls@2 && cat ./coverage/lcov.info | coveralls" -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nzh 2 | 3 | `Nzh` 适用于需要转换**阿拉伯数字**与**中文数字**的场景。 4 | 特点如下: 5 | - 以字符串的方式转换,没有超大数及浮点数等问题(请自行对原数据进行四舍五入等操作) 6 | - 支持科学记数法字符串的转换 7 | - 支持口语化 8 | - 支持自定义转换(不论是`兆`,`京`还是`厘`都可以用) 9 | - 对超大数支持用争议较少的`万万亿`代替`亿亿` 10 | - 当然,你还可以把中文数字再转回阿拉伯数字 11 | 12 | ## 安装 13 | 14 | ```sh 15 | $ npm install nzh --save 16 | $ bower install nzh --save 17 | ``` 18 | 19 | ## 引用 20 | 21 | ```javascript 22 | var Nzh = require("nzh"); 23 | var nzhcn = require("nzh/cn"); //直接使用简体中文 24 | var nzhhk = require("nzh/hk"); //繁体中文 25 | ``` 26 | > 注: 浏览器直接引用请使用 `dist/`文件夹中的文件 (适配CMD,AMD); 27 | 28 | ## 示例 29 | 30 | ```javascript 31 | var nzhcn = Nzh.cn; // 使用简体中文, 另外有 Nzh.hk -- 繁体中文 32 | 33 | nzhcn.encodeS(100111); // 转中文小写 >> 十万零一百一十一 34 | nzhcn.encodeB(100111); // 转中文大写 >> 壹拾万零壹佰壹拾壹 35 | nzhcn.encodeS("1.23456789e+21"); // 科学记数法字符串 >> 十二万三千四百五十六万万七千八百九十万亿 36 | nzhcn.toMoney("100111.11"); // 转中文金额 >> 人民币壹拾万零壹佰壹拾壹元壹角壹分 37 | ``` 38 | 39 | ## API 40 | 41 | ### Nzh.cn / Nzh.hk 42 | 43 | 为方便使用,默认实现了两个对像: 44 | 45 | - `Nzh.cn` 简体中文 46 | - `Nzh.hk` 正体中文(繁体中文) 47 | 48 | 都包含以下方法: 49 | 50 | - `encodeS(num,options)` 转中文小写 51 | - `encodeB(num,options)` 转中文大写 52 | - `toMoney(num,options)` 转中文金额 53 | - `decodeS(zh_num)` 中文小写转数字 54 | - `decodeB(zh_num)` 中文大写转数字 55 | 56 | ```javascript 57 | // options.tenMin 58 | 59 | // encodeS默认true 60 | nzhcn.encodeS("13.5"); // 十三点五 61 | nzhcn.encodeS("13.5", {tenMin:false}); // 一十三点五 62 | // encodeB默人false 63 | nzhcn.encodeB("13.5"); // 壹拾叁點伍 64 | nzhcn.encodeB("13.5", {tenMin:true}); // 拾叁點伍 65 | 66 | // options.ww 67 | 68 | //Nzh.cn和Nzh.hk未引入兆、京等单位,超千万亿位时,默认以争议较少的万万亿为单位 69 | nzhcn.encodeS(1e16); // 一万万亿 70 | nzhcn.encodeS(1e16, {ww: false}); // 一亿亿 71 | 72 | 73 | // options.outputString 74 | 75 | console.log(nzhcn.decodeS('一万万万万亿', {outputString: false})); // 1e+24 76 | console.log(nzhcn.decodeS('一万万万万亿', {outputString: true})); // "1000000000000000000000000" 77 | 78 | // options.complete 79 | 80 | nzhcn.toMoney("1"); //人民币壹元整 81 | nzhcn.toMoney("1",{complete:true}); //人民币壹元零角零分 82 | nzhcn.toMoney("0.1"); //人民币壹角 83 | nzhcn.toMoney("0.1",{unOmitYuan:true}); //人民币零元壹角 84 | nzhcn.toMoney("0.1",{complete:true}); //人民币零元壹角零分 85 | 86 | //outSymbol 默认 true 87 | nzhcn.toMoney("1"); //人民币壹元整 88 | nzhcn.toMoney("1",{outSymbol:false}); //壹元整 89 | ``` 90 | ### options 说明 91 | - `tenMin`: 十的口语化开关, 默认值为 `false` 92 | - *注: `Nzh.cn`和`Nzh.hk`中的`encodeS`方法默认 `true`* 93 | - `ww`: "万万"化开关, 默认值为 `true` 94 | - `outputString` 中文数字转阿阿拉伯数字时, 输出为字符串类型, 解决输出对出超大数时可能输出科学计数法的问题,默认 `false`; 95 | - `unOmitYuan`: 个为零时不省略元, `toMoney` 函数专用配置, 默认 `false` 96 | - `complete`: 输出完整金额开关, `toMoney` 函数专用配置, 默认 `false` 97 | - `forceZheng`: 以输出结果加“整”(只要输出的结果没有到分位就加“整”), `toMoney` 函数专用配置, 默认 `false` 98 | - `outSymbol`: 输出金额前缀字符, `toMoney` 函数专用配置, 默认 `true` 99 | 100 | ### new Nzh(langs) 自定义 101 | 102 | ```javascript 103 | var nzh = new Nzh({ 104 | ch: "〇壹贰叁肆伍陆柒捌玖", // 数字字符 105 | ch_u: "个十百千万亿兆京", // 数位单位字符,万以下十进制,万以上万进制,个位不能省略 106 | ch_f: "负", // 负字符 107 | ch_d: "点", // 小数点字符 108 | m_u: "元角分厘", // 金额单位 109 | m_t: "人民币", // 金额前缀 110 | m_z: "正" // 金额无小数后缀 111 | }); 112 | nzh.encode("10001000000000000"); // 壹京〇壹兆 113 | nzh.decode("壹兆"); // 1000000000000 114 | nzh.toMoney("1.234"); // 人民币壹元贰角叁分肆厘 115 | ``` 116 | 117 | #### nzh.encode(num,options) 118 | 数字转中文 119 | 120 | #### nzh.decode(zh_num,options) 121 | 中文转数字 122 | 123 | #### nzh.toMoney(num,options) 124 | 数字转金额 125 | 126 | ## 参考资料 127 | - [繁读法](https://baike.baidu.com/item/%E7%B9%81%E8%AF%BB%E6%B3%95) 128 | - [中文数字](https://baike.baidu.com/item/%E4%B8%AD%E6%96%87%E6%95%B0%E5%AD%97) 129 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nzh", 3 | "description": "数字转中文,大写,金额", 4 | "main": "dist/nzh.js", 5 | "authors": [ 6 | "cnwhy " 7 | ], 8 | "license": "BSD-2-Clause", 9 | "keywords": [ 10 | "数字转中文", 11 | "数字转金额", 12 | "中文数字转阿拉伯数字", 13 | "中文数字" 14 | ], 15 | "homepage": "https://github.com/cnwhy/nzh", 16 | "ignore": [ 17 | "**/.*", 18 | "./index.html", 19 | "node_modules", 20 | "bower_components", 21 | "test", 22 | "demo", 23 | "docs", 24 | "browser-source" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /cn.js: -------------------------------------------------------------------------------- 1 | var getNzhObjByLang = require("./src/autoGet"); 2 | var langs = { 3 | s: require("./src/langs/cn_s"), 4 | b: require("./src/langs/cn_b"), 5 | } 6 | module.exports = getNzhObjByLang(langs.s, langs.b); -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 在线转换 6 | 7 | 8 | 9 | 10 | 11 |
结果:
12 | 13 | 49 | 50 | -------------------------------------------------------------------------------- /dist/nzh.cn.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * nzh v1.0.14 3 | * Homepage http://cnwhy.github.io/nzh 4 | * License BSD-2-Clause 5 | */ 6 | 7 | (function (global, factory) { 8 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 9 | typeof define === 'function' && define.amd ? define(factory) : 10 | (global.Nzh = factory()); 11 | }(this, (function () { 'use strict'; 12 | 13 | function createCommonjsModule(fn, module) { 14 | return module = { exports: {} }, fn(module, module.exports), module.exports; 15 | } 16 | 17 | var utils = createCommonjsModule(function (module, exports) { 18 | var REG_NUMBER = /^([+-])?0*(\d+)(\.(\d+))?$/; 19 | var REG_E = /^([+-])?0*(\d+)(\.(\d+))?e(([+-])?(\d+))$/i; 20 | 21 | /** 22 | * 科学计数法转十进制 23 | * 24 | * @param {string} num 科学记数法字符串 25 | * @returns string 26 | */ 27 | var e2ten = exports.e2ten = function (num) { 28 | var result = REG_E.exec(num.toString()); 29 | if (!result) return num; 30 | var zs = result[2] 31 | , xs = result[4] || "" 32 | , e = result[5] ? +result[5] : 0; 33 | if (e > 0) { 34 | var _zs = xs.substr(0, e); 35 | _zs = _zs.length < e ? _zs + new Array(e - _zs.length + 1).join("0") : _zs; 36 | xs = xs.substr(e); 37 | zs += _zs; 38 | } else { 39 | e = -e; 40 | var s_start = zs.length - e; 41 | s_start = s_start < 0 ? 0 : s_start; 42 | var _xs = zs.substr(s_start, e); 43 | _xs = _xs.length < e ? new Array(e - _xs.length + 1).join("0") + _xs : _xs; 44 | zs = zs.substring(0, s_start); 45 | xs = _xs + xs; 46 | } 47 | zs = zs == "" ? "0" : zs; 48 | return (result[1] == "-" ? "-" : "") + zs + (xs ? "." + xs : ""); 49 | }; 50 | 51 | /** 52 | * 分析数字字符串 53 | * 54 | * @param {string} num NumberString 55 | * @returns object 56 | */ 57 | exports.getNumbResult = function (num) { 58 | var result = REG_NUMBER.exec(num.toString()); 59 | if (!result && REG_E.test(num.toString())) { 60 | result = REG_NUMBER.exec(e2ten(num.toString())); 61 | } 62 | if (result) { 63 | return { 64 | int: result[2], 65 | decimal: result[4], 66 | minus: result[1] == "-", 67 | num: result.slice(1, 3).join('') 68 | } 69 | } 70 | }; 71 | 72 | /** 73 | * 数组归一 (按索引覆盖合并数组,并清空被合并的数组) 74 | * 75 | * @param {array} baseArray 基础数组 76 | * @param {...array} array1 77 | * @returns array 78 | */ 79 | exports.centerArray = function centerArray(baseArray, array1 /*[, array2[, ...[, arrayN]]]*/) { 80 | baseArray.splice.apply(baseArray, [0, array1.length].concat(array1.splice(0, array1.length))); 81 | if (arguments.length > 2) { 82 | var r = [].slice.call(arguments, 2); 83 | r.unshift(baseArray); 84 | centerArray.apply(null, r); 85 | } 86 | return baseArray; 87 | }; 88 | 89 | /** 90 | * 检查对像属性 (非原型链) 91 | * 92 | * @param {object} obj 93 | * @param {string} key 94 | * @returns 95 | */ 96 | var hasAttr = exports.hasAttr = function (obj, key) { 97 | return Object.prototype.hasOwnProperty.call(obj, key); 98 | }; 99 | 100 | /** 101 | * 扩展对像(浅复制) 102 | * 103 | * @param {object} obj 104 | * @param {object} obj1 105 | * @returns 106 | */ 107 | exports.extend = function (obj) { 108 | var name 109 | , target = arguments[0] || {}; 110 | var objs = Array.prototype.slice.call(arguments, 1); 111 | 112 | for (var i = 0; i < objs.length; i++) { 113 | var _obj = objs[i]; 114 | for (name in _obj) { 115 | if (hasAttr(_obj, name)) { 116 | target[name] = _obj[name]; 117 | } 118 | } 119 | } 120 | return target; 121 | }; 122 | 123 | 124 | /** 125 | * 获取真实数位 126 | * 127 | * @param {number} index 中文单位的索引 128 | */ 129 | exports.getDigit = function (index) { 130 | return index >= 5 ? (index - 4) * 4 + 4 : index; 131 | }; 132 | 133 | /** 134 | * 往数组头部插入0 135 | * 136 | * @param {array} arr 137 | * @param {number} n 138 | */ 139 | exports.unshiftZero = function (arr, n) { 140 | if (n == null) n = 1; 141 | if (n <= 0) return; 142 | for (; n--;) arr.unshift(0); 143 | }; 144 | 145 | /** 146 | * 清理多余"零" 147 | * 148 | * @param {any} str 149 | * @param {any} zero "零"字符 150 | * @param {any} type 清理模式 ^ - 开头, $ - 结尾, nto1 - 多个连续变一个 151 | * @returns 152 | */ 153 | exports.clearZero = function (str, zero, type) { 154 | if (str == null) return ""; 155 | var reg0 = ~"*.?+$^[](){}|\\/".indexOf(zero) ? "\\" + zero : zero; 156 | var arg_s = new RegExp("^" + reg0 + "+") 157 | , arg_e = new RegExp(reg0 + "+$") 158 | , arg_d = new RegExp(reg0 + "{2}", "g"); 159 | str = str.toString(); 160 | if (type == "^") { 161 | str = str.replace(arg_s, ""); 162 | } 163 | if (!type || type == "$") { 164 | str = str.replace(arg_e, ""); 165 | } 166 | if (!type || type == "nto1") { 167 | str = str.replace(arg_d, zero); 168 | } 169 | return str; 170 | }; 171 | }); 172 | var utils_1 = utils.e2ten; 173 | var utils_2 = utils.getNumbResult; 174 | var utils_3 = utils.centerArray; 175 | var utils_4 = utils.hasAttr; 176 | var utils_5 = utils.extend; 177 | var utils_6 = utils.getDigit; 178 | var utils_7 = utils.unshiftZero; 179 | var utils_8 = utils.clearZero; 180 | 181 | /** 182 | * 阿拉伯数字转中文数字 183 | * 184 | * @param {String} num 阿拉伯数字/字符串 , 科学记数法字符串 185 | * @param {Object} opration 转换配置 186 | * { 187 | * ww: {万万化单位 | false} 188 | * tenMin: {十的口语化 | false} 189 | * } 190 | * @returns String 191 | */ 192 | function CL(num, options) { 193 | var result = utils.getNumbResult(num); 194 | if (!result) { 195 | return num; 196 | } 197 | options = options ? options : {}; 198 | var ch = this.ch //数字 199 | , ch_u = this.ch_u //单位 200 | , ch_f = this.ch_f || "" //负 201 | , ch_d = this.ch_d || "." //点 202 | , n0 = ch.charAt(0); //零 203 | var _int = result.int //整数部分 204 | , _decimal = result.decimal //小数部分 205 | , _minus = result.minus; //负数标识 206 | var int = "" 207 | , dicimal = "" 208 | , minus = _minus ? ch_f : ''; //符号位 209 | var encodeInt = function encodeInt(_int, _m, _dg) { 210 | _int = utils.getNumbResult(_int).int; 211 | var int = "" 212 | , tenm = arguments.length > 1 ? arguments[1] : options.tenMin 213 | , _length = _int.length; 214 | //一位整数 215 | if (_length == 1) return ch.charAt(+_int); 216 | if (_length <= 4) { //四位及以下 217 | for (var i = 0, n = _length; n--;) { 218 | var _num = +_int.charAt(i); 219 | int += (tenm && _length == 2 && i == 0 && _num == 1) ? "" : ch.charAt(_num); 220 | int += (_num && n ? ch_u.charAt(n) : ''); 221 | i++; 222 | } 223 | } else { //大数递归 224 | var d = _int.length / 4 >> 0 225 | , y = _int.length % 4; 226 | //"兆","京"等单位处理 227 | while (y == 0 || !ch_u.charAt(3 + d)) { 228 | y += 4; 229 | d--; 230 | } 231 | var _maxLeft = _int.substr(0, y), //最大单位前的数字 232 | _other = _int.substr(y); //剩余数字 233 | 234 | int = encodeInt(_maxLeft, tenm) + ch_u.charAt(3 + d) 235 | + (_other.charAt(0) == '0' ? n0 : '') //单位后有0则加零 236 | + encodeInt(_other, _other.length > 4 ? tenm : false); 237 | } 238 | int = utils.clearZero(int, n0); //修整零 239 | return int; 240 | }; 241 | 242 | //转换小数部分 243 | if (_decimal) { 244 | _decimal = utils.clearZero(_decimal, "0", "$"); //去除尾部0 245 | for (var x = 0; x < _decimal.length; x++) { 246 | dicimal += ch.charAt(+_decimal.charAt(x)); 247 | } 248 | dicimal = dicimal ? ch_d + dicimal : ""; 249 | } 250 | 251 | //转换整数部分 252 | int = encodeInt(_int); //转换整数 253 | 254 | //超级大数的万万化 255 | if (options.ww && ch_u.length > 5) { 256 | var dw_w = ch_u.charAt(4) 257 | , dw_y = ch_u.charAt(5); 258 | var lasty = int.lastIndexOf(dw_y); 259 | if (~lasty) { 260 | int = int.substring(0, lasty).replace(new RegExp(dw_y, 'g'), dw_w + dw_w) + int.substring(lasty); 261 | } 262 | } 263 | return minus + int + dicimal; 264 | } 265 | 266 | /** 267 | * 中文数字转阿拉伯数字 268 | * 269 | * @param {string} cnnumb 中文数字字符串 270 | * @returns Number 271 | */ 272 | function unCL(cnnumb, options) { 273 | cnnumb = cnnumb.toString(); 274 | var result = cnnumb.split(this.ch_d); 275 | var _int = result[0].replace(this.ch_f, "") 276 | , _decimal = result[1] 277 | , _minus = !!~result[0].indexOf(this.ch_f); 278 | 279 | var dw_s = this.ch_u.charAt(1) 280 | , dw_w = this.ch_u.charAt(4) 281 | , dw_y = this.ch_u.charAt(5); 282 | 283 | _int = _int.replace(new RegExp(dw_w + "{2}(?!"+dw_w+")", "g"), dw_y); 284 | var cnarr = _int.split(''); 285 | var dw = 0, maxdw = 0; 286 | var rnum_a = [], num_a = [], _num_a = []; 287 | for (var i = 0; i < cnarr.length; i++) { 288 | var chr = cnarr[i]; 289 | var n = 0, u = 0; 290 | if (~(n = this.ch.indexOf(chr))) { 291 | //_num = _num*10 + n; 292 | if (n > 0) _num_a.unshift(n); 293 | //_num_a.unshift(n); 294 | } else if (~(u = this.ch_u.indexOf(chr))) { 295 | var digit = utils.getDigit(u); 296 | if (dw > u) {//正常情况 297 | utils.unshiftZero(_num_a, digit); 298 | utils.centerArray(num_a, _num_a); 299 | } else if (u >= maxdw) {//后跟大单位 300 | if (i == 0) _num_a = [1]; 301 | utils.centerArray(rnum_a, num_a, _num_a); 302 | if (rnum_a.length > 0) utils.unshiftZero(rnum_a, digit); 303 | maxdw = u; 304 | } else { 305 | if (_num_a.length == 0 && dw_s == chr) _num_a = [1]; 306 | utils.centerArray(num_a, _num_a); 307 | utils.unshiftZero(num_a, utils.getDigit(u)); 308 | dw = u; 309 | } 310 | } 311 | } 312 | utils.centerArray(rnum_a, num_a, _num_a).reverse(); 313 | if (rnum_a.length == 0) rnum_a.push(0); 314 | var decimal = 0; 315 | if (_decimal) { 316 | rnum_a.push('.'); 317 | decimal = '0.'; 318 | for (var i = 0; i < _decimal.length; i++) { 319 | decimal += this.ch.indexOf(_decimal.charAt(i)); 320 | rnum_a.push(this.ch.indexOf(_decimal.charAt(i))); 321 | } 322 | decimal = +decimal; 323 | 324 | } 325 | if (_minus) rnum_a.unshift('-'); 326 | return (options && options.outputString) ? rnum_a.join('') : parseFloat(rnum_a.join('')); 327 | } 328 | 329 | /** 330 | * 阿拉伯数字转金额 331 | * 332 | * @param {String} num 阿拉伯数字/字符串 , 科学记数法字符串 333 | * @param {Object} options 转换配置 334 | * { 335 | * ww:{万万化开关 | true}, 336 | * unOmitYuan: {整数为0时不省略元| false}, 337 | * complete:{完整金额格式 | false}, 338 | * outSymbol:{是否输出金额符号 | true} 339 | * forceZheng:{以转换结果加“整” | false} 340 | * } 341 | * @returns String 342 | */ 343 | function toMoney(num, options) { 344 | var def = { ww: true, complete: false, outSymbol: true, unOmitYuan: false, forceZheng: false }; 345 | var result = utils.getNumbResult(num); 346 | var ch_0 = this.ch.charAt(0); 347 | options = typeof options == "object" ? options : {}; 348 | if (!result) { return num; } 349 | options = utils.extend(def, options); 350 | 351 | var _int = result.int 352 | , _decimal = result.decimal || ""; 353 | var t_str = options.outSymbol ? this.m_t : "" 354 | , zs_str = result.minus ? this.ch_f : "" 355 | , xs_str = ""; 356 | if (options.complete) { 357 | for (var i = 1; i < this.m_u.length; i++) { 358 | xs_str += CL.call(this, _decimal.charAt(i - 1) || "0") + this.m_u.charAt(i); 359 | } 360 | zs_str += CL.call(this, _int, options) + this.m_u.charAt(0); 361 | } else { 362 | var hasYuan = options.unOmitYuan || _int !== '0'; 363 | _decimal = _decimal.substr(0, this.m_u.length-1); 364 | _decimal = utils.clearZero(_decimal, "0", "$"); //去除尾部的0 365 | if (_decimal) { 366 | var mark_0; 367 | for (var i = 0; i < this.m_u.length - 1; i++) { 368 | if (_decimal.charAt(i) && _decimal.charAt(i) != "0") { 369 | xs_str += CL.call(this, _decimal.charAt(i)) + this.m_u.charAt(i + 1); 370 | mark_0 = false; 371 | } 372 | if (_decimal.charAt(i) === "0" && !mark_0) { 373 | if (i != 0 || _int !== "0") xs_str += ch_0; //当没有输出元时,小数前无需加零 374 | mark_0 = true; 375 | } 376 | } 377 | //if(_num == "0"){xs_str = utils.clearZero(xs_str,ch_0,"^")} 378 | } 379 | if (hasYuan || !xs_str) { 380 | zs_str += CL.call(this, _int, options) + this.m_u.charAt(0); 381 | } 382 | if(!options.forceZheng) { 383 | zs_str += result.decimal ? "" : this.m_z; 384 | }else if(xs_str == '' || xs_str.charAt(xs_str.length-1) !== this.m_u[2]){ 385 | xs_str += this.m_z; 386 | } 387 | // if(result.minus) t_str += this.ch_f; 388 | if(options.forceZheng); 389 | } 390 | return t_str + zs_str + xs_str; 391 | } 392 | 393 | var src = { 394 | CL: CL, 395 | unCL: unCL, 396 | toMoney: toMoney 397 | }; 398 | 399 | function getNzhObjByLang(lang_s, lang_b) { 400 | return { 401 | encodeS: function (num, options) { 402 | options = utils.extend({ ww: true, tenMin: true }, options); 403 | return src.CL.call(lang_s, num, options); 404 | }, 405 | encodeB: function (num, options) { 406 | options = utils.extend({ ww: true }, options); 407 | return src.CL.call(lang_b, num, options); 408 | }, 409 | decodeS: function () { 410 | return src.unCL.apply(lang_s, arguments); 411 | }, 412 | decodeB: function () { 413 | return src.unCL.apply(lang_b, arguments); 414 | }, 415 | toMoney: function (num, options) { 416 | options = utils.extend({ ww: true }, options); 417 | return src.toMoney.call(lang_b, num, options); 418 | } 419 | } 420 | } 421 | var autoGet = getNzhObjByLang; 422 | 423 | var cn_s = { 424 | ch: '零一二三四五六七八九' 425 | ,ch_u: '个十百千万亿' 426 | ,ch_f: '负' 427 | ,ch_d: '点' 428 | }; 429 | 430 | var cn_b = { 431 | ch: '零壹贰叁肆伍陆柒捌玖' 432 | ,ch_u: '个拾佰仟万亿' 433 | ,ch_f: '负' 434 | ,ch_d: '点' 435 | ,m_t: '人民币' 436 | ,m_z: '整' 437 | ,m_u: '元角分' 438 | }; 439 | 440 | var langs = { 441 | s: cn_s, 442 | b: cn_b, 443 | }; 444 | var cn = autoGet(langs.s, langs.b); 445 | 446 | return cn; 447 | 448 | }))); 449 | -------------------------------------------------------------------------------- /dist/nzh.cn.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * nzh v1.0.14 3 | * Homepage http://cnwhy.github.io/nzh 4 | * License BSD-2-Clause 5 | */ 6 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Nzh=e()}(this,function(){"use strict";function t(t,e){var r=i.getNumbResult(t);if(!r)return t;e=e||{};var n=this.ch,c=this.ch_u,h=this.ch_f||"",u=this.ch_d||".",a=n.charAt(0),s=r.int,o=r.decimal,l=r.minus,f="",g="",p=l?h:"";if(o){o=i.clearZero(o,"0","$");for(var d=0;d1?arguments[1]:e.tenMin,l=r.length;if(1==l)return n.charAt(+r);if(l<=4)for(var f=0,g=l;g--;){var p=+r.charAt(f);s+=o&&2==l&&0==f&&1==p?"":n.charAt(p),s+=p&&g?c.charAt(g):"",f++}else{for(var d=r.length/4>>0,A=r.length%4;0==A||!c.charAt(3+d);)A+=4,d--;var m=r.substr(0,A),v=r.substr(A);s=t(m,o)+c.charAt(3+d)+("0"==v.charAt(0)?a:"")+t(v,v.length>4&&o)}return s=i.clearZero(s,a)}(s),e.ww&&c.length>5){var A=c.charAt(4),m=c.charAt(5),v=f.lastIndexOf(m);~v&&(f=f.substring(0,v).replace(new RegExp(m,"g"),A+A)+f.substring(v))}return p+f+g}function e(t,e){t=t.toString();var r=t.split(this.ch_d),n=r[0].replace(this.ch_f,""),c=r[1],h=!!~r[0].indexOf(this.ch_f),u=this.ch_u.charAt(1),a=this.ch_u.charAt(4),s=this.ch_u.charAt(5);n=n.replace(new RegExp(a+"{2}(?!"+a+")","g"),s);for(var o=n.split(""),l=0,f=0,g=[],p=[],d=[],A=0;A0&&d.unshift(v);else if(~(_=this.ch_u.indexOf(m))){var x=i.getDigit(_);l>_?(i.unshiftZero(d,x),i.centerArray(p,d)):_>=f?(0==A&&(d=[1]),i.centerArray(g,p,d),g.length>0&&i.unshiftZero(g,x),f=_):(0==d.length&&u==m&&(d=[1]),i.centerArray(p,d),i.unshiftZero(p,i.getDigit(_)),l=_)}}i.centerArray(g,p,d).reverse(),0==g.length&&g.push(0);var y=0;if(c){g.push("."),y="0.";for(var A=0;A0){var h=i.substr(0,c);h=h.length2){var n=[].slice.call(arguments,2);n.unshift(e),t.apply(null,n)}return e};var c=e.hasAttr=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)};e.extend=function(t){for(var e,r=arguments[0]||{},n=Array.prototype.slice.call(arguments,1),i=0;i=5?4*(t-4)+4:t},e.unshiftZero=function(t,e){if(null==e&&(e=1),!(e<=0))for(;e--;)t.unshift(0)},e.clearZero=function(t,e,r){if(null==t)return"";var n=~"*.?+$^[](){}|\\/".indexOf(e)?"\\"+e:e,i=new RegExp("^"+n+"+"),c=new RegExp(n+"+$"),h=new RegExp(n+"{2}","g");return t=t.toString(),"^"==r&&(t=t.replace(i,"")),r&&"$"!=r||(t=t.replace(c,"")),r&&"nto1"!=r||(t=t.replace(h,e)),t}}),c=(i.e2ten,i.getNumbResult,i.centerArray,i.hasAttr,i.extend,i.getDigit,i.unshiftZero,i.clearZero,{CL:t,unCL:e,toMoney:r}),h=n,u={ch:"零一二三四五六七八九",ch_u:"个十百千万亿",ch_f:"负",ch_d:"点"},a={ch:"零壹贰叁肆伍陆柒捌玖",ch_u:"个拾佰仟万亿",ch_f:"负",ch_d:"点",m_t:"人民币",m_z:"整",m_u:"元角分"},s={s:u,b:a};return h(s.s,s.b)}); -------------------------------------------------------------------------------- /dist/nzh.hk.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * nzh v1.0.14 3 | * Homepage http://cnwhy.github.io/nzh 4 | * License BSD-2-Clause 5 | */ 6 | 7 | (function (global, factory) { 8 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 9 | typeof define === 'function' && define.amd ? define(factory) : 10 | (global.Nzh = factory()); 11 | }(this, (function () { 'use strict'; 12 | 13 | function createCommonjsModule(fn, module) { 14 | return module = { exports: {} }, fn(module, module.exports), module.exports; 15 | } 16 | 17 | var utils = createCommonjsModule(function (module, exports) { 18 | var REG_NUMBER = /^([+-])?0*(\d+)(\.(\d+))?$/; 19 | var REG_E = /^([+-])?0*(\d+)(\.(\d+))?e(([+-])?(\d+))$/i; 20 | 21 | /** 22 | * 科学计数法转十进制 23 | * 24 | * @param {string} num 科学记数法字符串 25 | * @returns string 26 | */ 27 | var e2ten = exports.e2ten = function (num) { 28 | var result = REG_E.exec(num.toString()); 29 | if (!result) return num; 30 | var zs = result[2] 31 | , xs = result[4] || "" 32 | , e = result[5] ? +result[5] : 0; 33 | if (e > 0) { 34 | var _zs = xs.substr(0, e); 35 | _zs = _zs.length < e ? _zs + new Array(e - _zs.length + 1).join("0") : _zs; 36 | xs = xs.substr(e); 37 | zs += _zs; 38 | } else { 39 | e = -e; 40 | var s_start = zs.length - e; 41 | s_start = s_start < 0 ? 0 : s_start; 42 | var _xs = zs.substr(s_start, e); 43 | _xs = _xs.length < e ? new Array(e - _xs.length + 1).join("0") + _xs : _xs; 44 | zs = zs.substring(0, s_start); 45 | xs = _xs + xs; 46 | } 47 | zs = zs == "" ? "0" : zs; 48 | return (result[1] == "-" ? "-" : "") + zs + (xs ? "." + xs : ""); 49 | }; 50 | 51 | /** 52 | * 分析数字字符串 53 | * 54 | * @param {string} num NumberString 55 | * @returns object 56 | */ 57 | exports.getNumbResult = function (num) { 58 | var result = REG_NUMBER.exec(num.toString()); 59 | if (!result && REG_E.test(num.toString())) { 60 | result = REG_NUMBER.exec(e2ten(num.toString())); 61 | } 62 | if (result) { 63 | return { 64 | int: result[2], 65 | decimal: result[4], 66 | minus: result[1] == "-", 67 | num: result.slice(1, 3).join('') 68 | } 69 | } 70 | }; 71 | 72 | /** 73 | * 数组归一 (按索引覆盖合并数组,并清空被合并的数组) 74 | * 75 | * @param {array} baseArray 基础数组 76 | * @param {...array} array1 77 | * @returns array 78 | */ 79 | exports.centerArray = function centerArray(baseArray, array1 /*[, array2[, ...[, arrayN]]]*/) { 80 | baseArray.splice.apply(baseArray, [0, array1.length].concat(array1.splice(0, array1.length))); 81 | if (arguments.length > 2) { 82 | var r = [].slice.call(arguments, 2); 83 | r.unshift(baseArray); 84 | centerArray.apply(null, r); 85 | } 86 | return baseArray; 87 | }; 88 | 89 | /** 90 | * 检查对像属性 (非原型链) 91 | * 92 | * @param {object} obj 93 | * @param {string} key 94 | * @returns 95 | */ 96 | var hasAttr = exports.hasAttr = function (obj, key) { 97 | return Object.prototype.hasOwnProperty.call(obj, key); 98 | }; 99 | 100 | /** 101 | * 扩展对像(浅复制) 102 | * 103 | * @param {object} obj 104 | * @param {object} obj1 105 | * @returns 106 | */ 107 | exports.extend = function (obj) { 108 | var name 109 | , target = arguments[0] || {}; 110 | var objs = Array.prototype.slice.call(arguments, 1); 111 | 112 | for (var i = 0; i < objs.length; i++) { 113 | var _obj = objs[i]; 114 | for (name in _obj) { 115 | if (hasAttr(_obj, name)) { 116 | target[name] = _obj[name]; 117 | } 118 | } 119 | } 120 | return target; 121 | }; 122 | 123 | 124 | /** 125 | * 获取真实数位 126 | * 127 | * @param {number} index 中文单位的索引 128 | */ 129 | exports.getDigit = function (index) { 130 | return index >= 5 ? (index - 4) * 4 + 4 : index; 131 | }; 132 | 133 | /** 134 | * 往数组头部插入0 135 | * 136 | * @param {array} arr 137 | * @param {number} n 138 | */ 139 | exports.unshiftZero = function (arr, n) { 140 | if (n == null) n = 1; 141 | if (n <= 0) return; 142 | for (; n--;) arr.unshift(0); 143 | }; 144 | 145 | /** 146 | * 清理多余"零" 147 | * 148 | * @param {any} str 149 | * @param {any} zero "零"字符 150 | * @param {any} type 清理模式 ^ - 开头, $ - 结尾, nto1 - 多个连续变一个 151 | * @returns 152 | */ 153 | exports.clearZero = function (str, zero, type) { 154 | if (str == null) return ""; 155 | var reg0 = ~"*.?+$^[](){}|\\/".indexOf(zero) ? "\\" + zero : zero; 156 | var arg_s = new RegExp("^" + reg0 + "+") 157 | , arg_e = new RegExp(reg0 + "+$") 158 | , arg_d = new RegExp(reg0 + "{2}", "g"); 159 | str = str.toString(); 160 | if (type == "^") { 161 | str = str.replace(arg_s, ""); 162 | } 163 | if (!type || type == "$") { 164 | str = str.replace(arg_e, ""); 165 | } 166 | if (!type || type == "nto1") { 167 | str = str.replace(arg_d, zero); 168 | } 169 | return str; 170 | }; 171 | }); 172 | var utils_1 = utils.e2ten; 173 | var utils_2 = utils.getNumbResult; 174 | var utils_3 = utils.centerArray; 175 | var utils_4 = utils.hasAttr; 176 | var utils_5 = utils.extend; 177 | var utils_6 = utils.getDigit; 178 | var utils_7 = utils.unshiftZero; 179 | var utils_8 = utils.clearZero; 180 | 181 | /** 182 | * 阿拉伯数字转中文数字 183 | * 184 | * @param {String} num 阿拉伯数字/字符串 , 科学记数法字符串 185 | * @param {Object} opration 转换配置 186 | * { 187 | * ww: {万万化单位 | false} 188 | * tenMin: {十的口语化 | false} 189 | * } 190 | * @returns String 191 | */ 192 | function CL(num, options) { 193 | var result = utils.getNumbResult(num); 194 | if (!result) { 195 | return num; 196 | } 197 | options = options ? options : {}; 198 | var ch = this.ch //数字 199 | , ch_u = this.ch_u //单位 200 | , ch_f = this.ch_f || "" //负 201 | , ch_d = this.ch_d || "." //点 202 | , n0 = ch.charAt(0); //零 203 | var _int = result.int //整数部分 204 | , _decimal = result.decimal //小数部分 205 | , _minus = result.minus; //负数标识 206 | var int = "" 207 | , dicimal = "" 208 | , minus = _minus ? ch_f : ''; //符号位 209 | var encodeInt = function encodeInt(_int, _m, _dg) { 210 | _int = utils.getNumbResult(_int).int; 211 | var int = "" 212 | , tenm = arguments.length > 1 ? arguments[1] : options.tenMin 213 | , _length = _int.length; 214 | //一位整数 215 | if (_length == 1) return ch.charAt(+_int); 216 | if (_length <= 4) { //四位及以下 217 | for (var i = 0, n = _length; n--;) { 218 | var _num = +_int.charAt(i); 219 | int += (tenm && _length == 2 && i == 0 && _num == 1) ? "" : ch.charAt(_num); 220 | int += (_num && n ? ch_u.charAt(n) : ''); 221 | i++; 222 | } 223 | } else { //大数递归 224 | var d = _int.length / 4 >> 0 225 | , y = _int.length % 4; 226 | //"兆","京"等单位处理 227 | while (y == 0 || !ch_u.charAt(3 + d)) { 228 | y += 4; 229 | d--; 230 | } 231 | var _maxLeft = _int.substr(0, y), //最大单位前的数字 232 | _other = _int.substr(y); //剩余数字 233 | 234 | int = encodeInt(_maxLeft, tenm) + ch_u.charAt(3 + d) 235 | + (_other.charAt(0) == '0' ? n0 : '') //单位后有0则加零 236 | + encodeInt(_other, _other.length > 4 ? tenm : false); 237 | } 238 | int = utils.clearZero(int, n0); //修整零 239 | return int; 240 | }; 241 | 242 | //转换小数部分 243 | if (_decimal) { 244 | _decimal = utils.clearZero(_decimal, "0", "$"); //去除尾部0 245 | for (var x = 0; x < _decimal.length; x++) { 246 | dicimal += ch.charAt(+_decimal.charAt(x)); 247 | } 248 | dicimal = dicimal ? ch_d + dicimal : ""; 249 | } 250 | 251 | //转换整数部分 252 | int = encodeInt(_int); //转换整数 253 | 254 | //超级大数的万万化 255 | if (options.ww && ch_u.length > 5) { 256 | var dw_w = ch_u.charAt(4) 257 | , dw_y = ch_u.charAt(5); 258 | var lasty = int.lastIndexOf(dw_y); 259 | if (~lasty) { 260 | int = int.substring(0, lasty).replace(new RegExp(dw_y, 'g'), dw_w + dw_w) + int.substring(lasty); 261 | } 262 | } 263 | return minus + int + dicimal; 264 | } 265 | 266 | /** 267 | * 中文数字转阿拉伯数字 268 | * 269 | * @param {string} cnnumb 中文数字字符串 270 | * @returns Number 271 | */ 272 | function unCL(cnnumb, options) { 273 | cnnumb = cnnumb.toString(); 274 | var result = cnnumb.split(this.ch_d); 275 | var _int = result[0].replace(this.ch_f, "") 276 | , _decimal = result[1] 277 | , _minus = !!~result[0].indexOf(this.ch_f); 278 | 279 | var dw_s = this.ch_u.charAt(1) 280 | , dw_w = this.ch_u.charAt(4) 281 | , dw_y = this.ch_u.charAt(5); 282 | 283 | _int = _int.replace(new RegExp(dw_w + "{2}(?!"+dw_w+")", "g"), dw_y); 284 | var cnarr = _int.split(''); 285 | var dw = 0, maxdw = 0; 286 | var rnum_a = [], num_a = [], _num_a = []; 287 | for (var i = 0; i < cnarr.length; i++) { 288 | var chr = cnarr[i]; 289 | var n = 0, u = 0; 290 | if (~(n = this.ch.indexOf(chr))) { 291 | //_num = _num*10 + n; 292 | if (n > 0) _num_a.unshift(n); 293 | //_num_a.unshift(n); 294 | } else if (~(u = this.ch_u.indexOf(chr))) { 295 | var digit = utils.getDigit(u); 296 | if (dw > u) {//正常情况 297 | utils.unshiftZero(_num_a, digit); 298 | utils.centerArray(num_a, _num_a); 299 | } else if (u >= maxdw) {//后跟大单位 300 | if (i == 0) _num_a = [1]; 301 | utils.centerArray(rnum_a, num_a, _num_a); 302 | if (rnum_a.length > 0) utils.unshiftZero(rnum_a, digit); 303 | maxdw = u; 304 | } else { 305 | if (_num_a.length == 0 && dw_s == chr) _num_a = [1]; 306 | utils.centerArray(num_a, _num_a); 307 | utils.unshiftZero(num_a, utils.getDigit(u)); 308 | dw = u; 309 | } 310 | } 311 | } 312 | utils.centerArray(rnum_a, num_a, _num_a).reverse(); 313 | if (rnum_a.length == 0) rnum_a.push(0); 314 | var decimal = 0; 315 | if (_decimal) { 316 | rnum_a.push('.'); 317 | decimal = '0.'; 318 | for (var i = 0; i < _decimal.length; i++) { 319 | decimal += this.ch.indexOf(_decimal.charAt(i)); 320 | rnum_a.push(this.ch.indexOf(_decimal.charAt(i))); 321 | } 322 | decimal = +decimal; 323 | 324 | } 325 | if (_minus) rnum_a.unshift('-'); 326 | return (options && options.outputString) ? rnum_a.join('') : parseFloat(rnum_a.join('')); 327 | } 328 | 329 | /** 330 | * 阿拉伯数字转金额 331 | * 332 | * @param {String} num 阿拉伯数字/字符串 , 科学记数法字符串 333 | * @param {Object} options 转换配置 334 | * { 335 | * ww:{万万化开关 | true}, 336 | * unOmitYuan: {整数为0时不省略元| false}, 337 | * complete:{完整金额格式 | false}, 338 | * outSymbol:{是否输出金额符号 | true} 339 | * forceZheng:{以转换结果加“整” | false} 340 | * } 341 | * @returns String 342 | */ 343 | function toMoney(num, options) { 344 | var def = { ww: true, complete: false, outSymbol: true, unOmitYuan: false, forceZheng: false }; 345 | var result = utils.getNumbResult(num); 346 | var ch_0 = this.ch.charAt(0); 347 | options = typeof options == "object" ? options : {}; 348 | if (!result) { return num; } 349 | options = utils.extend(def, options); 350 | 351 | var _int = result.int 352 | , _decimal = result.decimal || ""; 353 | var t_str = options.outSymbol ? this.m_t : "" 354 | , zs_str = result.minus ? this.ch_f : "" 355 | , xs_str = ""; 356 | if (options.complete) { 357 | for (var i = 1; i < this.m_u.length; i++) { 358 | xs_str += CL.call(this, _decimal.charAt(i - 1) || "0") + this.m_u.charAt(i); 359 | } 360 | zs_str += CL.call(this, _int, options) + this.m_u.charAt(0); 361 | } else { 362 | var hasYuan = options.unOmitYuan || _int !== '0'; 363 | _decimal = _decimal.substr(0, this.m_u.length-1); 364 | _decimal = utils.clearZero(_decimal, "0", "$"); //去除尾部的0 365 | if (_decimal) { 366 | var mark_0; 367 | for (var i = 0; i < this.m_u.length - 1; i++) { 368 | if (_decimal.charAt(i) && _decimal.charAt(i) != "0") { 369 | xs_str += CL.call(this, _decimal.charAt(i)) + this.m_u.charAt(i + 1); 370 | mark_0 = false; 371 | } 372 | if (_decimal.charAt(i) === "0" && !mark_0) { 373 | if (i != 0 || _int !== "0") xs_str += ch_0; //当没有输出元时,小数前无需加零 374 | mark_0 = true; 375 | } 376 | } 377 | //if(_num == "0"){xs_str = utils.clearZero(xs_str,ch_0,"^")} 378 | } 379 | if (hasYuan || !xs_str) { 380 | zs_str += CL.call(this, _int, options) + this.m_u.charAt(0); 381 | } 382 | if(!options.forceZheng) { 383 | zs_str += result.decimal ? "" : this.m_z; 384 | }else if(xs_str == '' || xs_str.charAt(xs_str.length-1) !== this.m_u[2]){ 385 | xs_str += this.m_z; 386 | } 387 | // if(result.minus) t_str += this.ch_f; 388 | if(options.forceZheng); 389 | } 390 | return t_str + zs_str + xs_str; 391 | } 392 | 393 | var src = { 394 | CL: CL, 395 | unCL: unCL, 396 | toMoney: toMoney 397 | }; 398 | 399 | function getNzhObjByLang(lang_s, lang_b) { 400 | return { 401 | encodeS: function (num, options) { 402 | options = utils.extend({ ww: true, tenMin: true }, options); 403 | return src.CL.call(lang_s, num, options); 404 | }, 405 | encodeB: function (num, options) { 406 | options = utils.extend({ ww: true }, options); 407 | return src.CL.call(lang_b, num, options); 408 | }, 409 | decodeS: function () { 410 | return src.unCL.apply(lang_s, arguments); 411 | }, 412 | decodeB: function () { 413 | return src.unCL.apply(lang_b, arguments); 414 | }, 415 | toMoney: function (num, options) { 416 | options = utils.extend({ ww: true }, options); 417 | return src.toMoney.call(lang_b, num, options); 418 | } 419 | } 420 | } 421 | var autoGet = getNzhObjByLang; 422 | 423 | var hk_s = { 424 | ch: '零一二三四五六七八九' 425 | ,ch_u: '個十百千萬億' 426 | ,ch_f: '負' 427 | ,ch_d: '點' 428 | }; 429 | 430 | var hk_b = { 431 | ch: '零壹貳參肆伍陸柒捌玖' 432 | ,ch_u: '個拾佰仟萬億' 433 | ,ch_f: '負' 434 | ,ch_d: '點' 435 | ,m_t: '$' 436 | ,m_z: '整' 437 | ,m_u: '圓角分' 438 | }; 439 | 440 | var langs = { 441 | s: hk_s, 442 | b: hk_b, 443 | }; 444 | var hk = autoGet(langs.s, langs.b); 445 | 446 | return hk; 447 | 448 | }))); 449 | -------------------------------------------------------------------------------- /dist/nzh.hk.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * nzh v1.0.14 3 | * Homepage http://cnwhy.github.io/nzh 4 | * License BSD-2-Clause 5 | */ 6 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Nzh=e()}(this,function(){"use strict";function t(t,e){var r=i.getNumbResult(t);if(!r)return t;e=e||{};var n=this.ch,c=this.ch_u,h=this.ch_f||"",u=this.ch_d||".",a=n.charAt(0),s=r.int,o=r.decimal,l=r.minus,f="",g="",p=l?h:"";if(o){o=i.clearZero(o,"0","$");for(var d=0;d1?arguments[1]:e.tenMin,l=r.length;if(1==l)return n.charAt(+r);if(l<=4)for(var f=0,g=l;g--;){var p=+r.charAt(f);s+=o&&2==l&&0==f&&1==p?"":n.charAt(p),s+=p&&g?c.charAt(g):"",f++}else{for(var d=r.length/4>>0,A=r.length%4;0==A||!c.charAt(3+d);)A+=4,d--;var m=r.substr(0,A),v=r.substr(A);s=t(m,o)+c.charAt(3+d)+("0"==v.charAt(0)?a:"")+t(v,v.length>4&&o)}return s=i.clearZero(s,a)}(s),e.ww&&c.length>5){var A=c.charAt(4),m=c.charAt(5),v=f.lastIndexOf(m);~v&&(f=f.substring(0,v).replace(new RegExp(m,"g"),A+A)+f.substring(v))}return p+f+g}function e(t,e){t=t.toString();var r=t.split(this.ch_d),n=r[0].replace(this.ch_f,""),c=r[1],h=!!~r[0].indexOf(this.ch_f),u=this.ch_u.charAt(1),a=this.ch_u.charAt(4),s=this.ch_u.charAt(5);n=n.replace(new RegExp(a+"{2}(?!"+a+")","g"),s);for(var o=n.split(""),l=0,f=0,g=[],p=[],d=[],A=0;A0&&d.unshift(v);else if(~(_=this.ch_u.indexOf(m))){var x=i.getDigit(_);l>_?(i.unshiftZero(d,x),i.centerArray(p,d)):_>=f?(0==A&&(d=[1]),i.centerArray(g,p,d),g.length>0&&i.unshiftZero(g,x),f=_):(0==d.length&&u==m&&(d=[1]),i.centerArray(p,d),i.unshiftZero(p,i.getDigit(_)),l=_)}}i.centerArray(g,p,d).reverse(),0==g.length&&g.push(0);var y=0;if(c){g.push("."),y="0.";for(var A=0;A0){var h=i.substr(0,c);h=h.length2){var n=[].slice.call(arguments,2);n.unshift(e),t.apply(null,n)}return e};var c=e.hasAttr=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)};e.extend=function(t){for(var e,r=arguments[0]||{},n=Array.prototype.slice.call(arguments,1),i=0;i=5?4*(t-4)+4:t},e.unshiftZero=function(t,e){if(null==e&&(e=1),!(e<=0))for(;e--;)t.unshift(0)},e.clearZero=function(t,e,r){if(null==t)return"";var n=~"*.?+$^[](){}|\\/".indexOf(e)?"\\"+e:e,i=new RegExp("^"+n+"+"),c=new RegExp(n+"+$"),h=new RegExp(n+"{2}","g");return t=t.toString(),"^"==r&&(t=t.replace(i,"")),r&&"$"!=r||(t=t.replace(c,"")),r&&"nto1"!=r||(t=t.replace(h,e)),t}}),c=(i.e2ten,i.getNumbResult,i.centerArray,i.hasAttr,i.extend,i.getDigit,i.unshiftZero,i.clearZero,{CL:t,unCL:e,toMoney:r}),h=n,u={ch:"零一二三四五六七八九",ch_u:"個十百千萬億",ch_f:"負",ch_d:"點"},a={ch:"零壹貳參肆伍陸柒捌玖",ch_u:"個拾佰仟萬億",ch_f:"負",ch_d:"點",m_t:"$",m_z:"整",m_u:"圓角分"},s={s:u,b:a};return h(s.s,s.b)}); -------------------------------------------------------------------------------- /dist/nzh.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * nzh v1.0.14 3 | * Homepage http://cnwhy.github.io/nzh 4 | * License BSD-2-Clause 5 | */ 6 | 7 | (function (global, factory) { 8 | typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 9 | typeof define === 'function' && define.amd ? define(factory) : 10 | (global.Nzh = factory()); 11 | }(this, (function () { 'use strict'; 12 | 13 | function createCommonjsModule(fn, module) { 14 | return module = { exports: {} }, fn(module, module.exports), module.exports; 15 | } 16 | 17 | var utils = createCommonjsModule(function (module, exports) { 18 | var REG_NUMBER = /^([+-])?0*(\d+)(\.(\d+))?$/; 19 | var REG_E = /^([+-])?0*(\d+)(\.(\d+))?e(([+-])?(\d+))$/i; 20 | 21 | /** 22 | * 科学计数法转十进制 23 | * 24 | * @param {string} num 科学记数法字符串 25 | * @returns string 26 | */ 27 | var e2ten = exports.e2ten = function (num) { 28 | var result = REG_E.exec(num.toString()); 29 | if (!result) return num; 30 | var zs = result[2] 31 | , xs = result[4] || "" 32 | , e = result[5] ? +result[5] : 0; 33 | if (e > 0) { 34 | var _zs = xs.substr(0, e); 35 | _zs = _zs.length < e ? _zs + new Array(e - _zs.length + 1).join("0") : _zs; 36 | xs = xs.substr(e); 37 | zs += _zs; 38 | } else { 39 | e = -e; 40 | var s_start = zs.length - e; 41 | s_start = s_start < 0 ? 0 : s_start; 42 | var _xs = zs.substr(s_start, e); 43 | _xs = _xs.length < e ? new Array(e - _xs.length + 1).join("0") + _xs : _xs; 44 | zs = zs.substring(0, s_start); 45 | xs = _xs + xs; 46 | } 47 | zs = zs == "" ? "0" : zs; 48 | return (result[1] == "-" ? "-" : "") + zs + (xs ? "." + xs : ""); 49 | }; 50 | 51 | /** 52 | * 分析数字字符串 53 | * 54 | * @param {string} num NumberString 55 | * @returns object 56 | */ 57 | exports.getNumbResult = function (num) { 58 | var result = REG_NUMBER.exec(num.toString()); 59 | if (!result && REG_E.test(num.toString())) { 60 | result = REG_NUMBER.exec(e2ten(num.toString())); 61 | } 62 | if (result) { 63 | return { 64 | int: result[2], 65 | decimal: result[4], 66 | minus: result[1] == "-", 67 | num: result.slice(1, 3).join('') 68 | } 69 | } 70 | }; 71 | 72 | /** 73 | * 数组归一 (按索引覆盖合并数组,并清空被合并的数组) 74 | * 75 | * @param {array} baseArray 基础数组 76 | * @param {...array} array1 77 | * @returns array 78 | */ 79 | exports.centerArray = function centerArray(baseArray, array1 /*[, array2[, ...[, arrayN]]]*/) { 80 | baseArray.splice.apply(baseArray, [0, array1.length].concat(array1.splice(0, array1.length))); 81 | if (arguments.length > 2) { 82 | var r = [].slice.call(arguments, 2); 83 | r.unshift(baseArray); 84 | centerArray.apply(null, r); 85 | } 86 | return baseArray; 87 | }; 88 | 89 | /** 90 | * 检查对像属性 (非原型链) 91 | * 92 | * @param {object} obj 93 | * @param {string} key 94 | * @returns 95 | */ 96 | var hasAttr = exports.hasAttr = function (obj, key) { 97 | return Object.prototype.hasOwnProperty.call(obj, key); 98 | }; 99 | 100 | /** 101 | * 扩展对像(浅复制) 102 | * 103 | * @param {object} obj 104 | * @param {object} obj1 105 | * @returns 106 | */ 107 | exports.extend = function (obj) { 108 | var name 109 | , target = arguments[0] || {}; 110 | var objs = Array.prototype.slice.call(arguments, 1); 111 | 112 | for (var i = 0; i < objs.length; i++) { 113 | var _obj = objs[i]; 114 | for (name in _obj) { 115 | if (hasAttr(_obj, name)) { 116 | target[name] = _obj[name]; 117 | } 118 | } 119 | } 120 | return target; 121 | }; 122 | 123 | 124 | /** 125 | * 获取真实数位 126 | * 127 | * @param {number} index 中文单位的索引 128 | */ 129 | exports.getDigit = function (index) { 130 | return index >= 5 ? (index - 4) * 4 + 4 : index; 131 | }; 132 | 133 | /** 134 | * 往数组头部插入0 135 | * 136 | * @param {array} arr 137 | * @param {number} n 138 | */ 139 | exports.unshiftZero = function (arr, n) { 140 | if (n == null) n = 1; 141 | if (n <= 0) return; 142 | for (; n--;) arr.unshift(0); 143 | }; 144 | 145 | /** 146 | * 清理多余"零" 147 | * 148 | * @param {any} str 149 | * @param {any} zero "零"字符 150 | * @param {any} type 清理模式 ^ - 开头, $ - 结尾, nto1 - 多个连续变一个 151 | * @returns 152 | */ 153 | exports.clearZero = function (str, zero, type) { 154 | if (str == null) return ""; 155 | var reg0 = ~"*.?+$^[](){}|\\/".indexOf(zero) ? "\\" + zero : zero; 156 | var arg_s = new RegExp("^" + reg0 + "+") 157 | , arg_e = new RegExp(reg0 + "+$") 158 | , arg_d = new RegExp(reg0 + "{2}", "g"); 159 | str = str.toString(); 160 | if (type == "^") { 161 | str = str.replace(arg_s, ""); 162 | } 163 | if (!type || type == "$") { 164 | str = str.replace(arg_e, ""); 165 | } 166 | if (!type || type == "nto1") { 167 | str = str.replace(arg_d, zero); 168 | } 169 | return str; 170 | }; 171 | }); 172 | var utils_1 = utils.e2ten; 173 | var utils_2 = utils.getNumbResult; 174 | var utils_3 = utils.centerArray; 175 | var utils_4 = utils.hasAttr; 176 | var utils_5 = utils.extend; 177 | var utils_6 = utils.getDigit; 178 | var utils_7 = utils.unshiftZero; 179 | var utils_8 = utils.clearZero; 180 | 181 | /** 182 | * 阿拉伯数字转中文数字 183 | * 184 | * @param {String} num 阿拉伯数字/字符串 , 科学记数法字符串 185 | * @param {Object} opration 转换配置 186 | * { 187 | * ww: {万万化单位 | false} 188 | * tenMin: {十的口语化 | false} 189 | * } 190 | * @returns String 191 | */ 192 | function CL(num, options) { 193 | var result = utils.getNumbResult(num); 194 | if (!result) { 195 | return num; 196 | } 197 | options = options ? options : {}; 198 | var ch = this.ch //数字 199 | , ch_u = this.ch_u //单位 200 | , ch_f = this.ch_f || "" //负 201 | , ch_d = this.ch_d || "." //点 202 | , n0 = ch.charAt(0); //零 203 | var _int = result.int //整数部分 204 | , _decimal = result.decimal //小数部分 205 | , _minus = result.minus; //负数标识 206 | var int = "" 207 | , dicimal = "" 208 | , minus = _minus ? ch_f : ''; //符号位 209 | var encodeInt = function encodeInt(_int, _m, _dg) { 210 | _int = utils.getNumbResult(_int).int; 211 | var int = "" 212 | , tenm = arguments.length > 1 ? arguments[1] : options.tenMin 213 | , _length = _int.length; 214 | //一位整数 215 | if (_length == 1) return ch.charAt(+_int); 216 | if (_length <= 4) { //四位及以下 217 | for (var i = 0, n = _length; n--;) { 218 | var _num = +_int.charAt(i); 219 | int += (tenm && _length == 2 && i == 0 && _num == 1) ? "" : ch.charAt(_num); 220 | int += (_num && n ? ch_u.charAt(n) : ''); 221 | i++; 222 | } 223 | } else { //大数递归 224 | var d = _int.length / 4 >> 0 225 | , y = _int.length % 4; 226 | //"兆","京"等单位处理 227 | while (y == 0 || !ch_u.charAt(3 + d)) { 228 | y += 4; 229 | d--; 230 | } 231 | var _maxLeft = _int.substr(0, y), //最大单位前的数字 232 | _other = _int.substr(y); //剩余数字 233 | 234 | int = encodeInt(_maxLeft, tenm) + ch_u.charAt(3 + d) 235 | + (_other.charAt(0) == '0' ? n0 : '') //单位后有0则加零 236 | + encodeInt(_other, _other.length > 4 ? tenm : false); 237 | } 238 | int = utils.clearZero(int, n0); //修整零 239 | return int; 240 | }; 241 | 242 | //转换小数部分 243 | if (_decimal) { 244 | _decimal = utils.clearZero(_decimal, "0", "$"); //去除尾部0 245 | for (var x = 0; x < _decimal.length; x++) { 246 | dicimal += ch.charAt(+_decimal.charAt(x)); 247 | } 248 | dicimal = dicimal ? ch_d + dicimal : ""; 249 | } 250 | 251 | //转换整数部分 252 | int = encodeInt(_int); //转换整数 253 | 254 | //超级大数的万万化 255 | if (options.ww && ch_u.length > 5) { 256 | var dw_w = ch_u.charAt(4) 257 | , dw_y = ch_u.charAt(5); 258 | var lasty = int.lastIndexOf(dw_y); 259 | if (~lasty) { 260 | int = int.substring(0, lasty).replace(new RegExp(dw_y, 'g'), dw_w + dw_w) + int.substring(lasty); 261 | } 262 | } 263 | return minus + int + dicimal; 264 | } 265 | 266 | /** 267 | * 中文数字转阿拉伯数字 268 | * 269 | * @param {string} cnnumb 中文数字字符串 270 | * @returns Number 271 | */ 272 | function unCL(cnnumb, options) { 273 | cnnumb = cnnumb.toString(); 274 | var result = cnnumb.split(this.ch_d); 275 | var _int = result[0].replace(this.ch_f, "") 276 | , _decimal = result[1] 277 | , _minus = !!~result[0].indexOf(this.ch_f); 278 | 279 | var dw_s = this.ch_u.charAt(1) 280 | , dw_w = this.ch_u.charAt(4) 281 | , dw_y = this.ch_u.charAt(5); 282 | 283 | _int = _int.replace(new RegExp(dw_w + "{2}(?!"+dw_w+")", "g"), dw_y); 284 | var cnarr = _int.split(''); 285 | var dw = 0, maxdw = 0; 286 | var rnum_a = [], num_a = [], _num_a = []; 287 | for (var i = 0; i < cnarr.length; i++) { 288 | var chr = cnarr[i]; 289 | var n = 0, u = 0; 290 | if (~(n = this.ch.indexOf(chr))) { 291 | //_num = _num*10 + n; 292 | if (n > 0) _num_a.unshift(n); 293 | //_num_a.unshift(n); 294 | } else if (~(u = this.ch_u.indexOf(chr))) { 295 | var digit = utils.getDigit(u); 296 | if (dw > u) {//正常情况 297 | utils.unshiftZero(_num_a, digit); 298 | utils.centerArray(num_a, _num_a); 299 | } else if (u >= maxdw) {//后跟大单位 300 | if (i == 0) _num_a = [1]; 301 | utils.centerArray(rnum_a, num_a, _num_a); 302 | if (rnum_a.length > 0) utils.unshiftZero(rnum_a, digit); 303 | maxdw = u; 304 | } else { 305 | if (_num_a.length == 0 && dw_s == chr) _num_a = [1]; 306 | utils.centerArray(num_a, _num_a); 307 | utils.unshiftZero(num_a, utils.getDigit(u)); 308 | dw = u; 309 | } 310 | } 311 | } 312 | utils.centerArray(rnum_a, num_a, _num_a).reverse(); 313 | if (rnum_a.length == 0) rnum_a.push(0); 314 | var decimal = 0; 315 | if (_decimal) { 316 | rnum_a.push('.'); 317 | decimal = '0.'; 318 | for (var i = 0; i < _decimal.length; i++) { 319 | decimal += this.ch.indexOf(_decimal.charAt(i)); 320 | rnum_a.push(this.ch.indexOf(_decimal.charAt(i))); 321 | } 322 | decimal = +decimal; 323 | 324 | } 325 | if (_minus) rnum_a.unshift('-'); 326 | return (options && options.outputString) ? rnum_a.join('') : parseFloat(rnum_a.join('')); 327 | } 328 | 329 | /** 330 | * 阿拉伯数字转金额 331 | * 332 | * @param {String} num 阿拉伯数字/字符串 , 科学记数法字符串 333 | * @param {Object} options 转换配置 334 | * { 335 | * ww:{万万化开关 | true}, 336 | * unOmitYuan: {整数为0时不省略元| false}, 337 | * complete:{完整金额格式 | false}, 338 | * outSymbol:{是否输出金额符号 | true} 339 | * forceZheng:{以转换结果加“整” | false} 340 | * } 341 | * @returns String 342 | */ 343 | function toMoney(num, options) { 344 | var def = { ww: true, complete: false, outSymbol: true, unOmitYuan: false, forceZheng: false }; 345 | var result = utils.getNumbResult(num); 346 | var ch_0 = this.ch.charAt(0); 347 | options = typeof options == "object" ? options : {}; 348 | if (!result) { return num; } 349 | options = utils.extend(def, options); 350 | 351 | var _int = result.int 352 | , _decimal = result.decimal || ""; 353 | var t_str = options.outSymbol ? this.m_t : "" 354 | , zs_str = result.minus ? this.ch_f : "" 355 | , xs_str = ""; 356 | if (options.complete) { 357 | for (var i = 1; i < this.m_u.length; i++) { 358 | xs_str += CL.call(this, _decimal.charAt(i - 1) || "0") + this.m_u.charAt(i); 359 | } 360 | zs_str += CL.call(this, _int, options) + this.m_u.charAt(0); 361 | } else { 362 | var hasYuan = options.unOmitYuan || _int !== '0'; 363 | _decimal = _decimal.substr(0, this.m_u.length-1); 364 | _decimal = utils.clearZero(_decimal, "0", "$"); //去除尾部的0 365 | if (_decimal) { 366 | var mark_0; 367 | for (var i = 0; i < this.m_u.length - 1; i++) { 368 | if (_decimal.charAt(i) && _decimal.charAt(i) != "0") { 369 | xs_str += CL.call(this, _decimal.charAt(i)) + this.m_u.charAt(i + 1); 370 | mark_0 = false; 371 | } 372 | if (_decimal.charAt(i) === "0" && !mark_0) { 373 | if (i != 0 || _int !== "0") xs_str += ch_0; //当没有输出元时,小数前无需加零 374 | mark_0 = true; 375 | } 376 | } 377 | //if(_num == "0"){xs_str = utils.clearZero(xs_str,ch_0,"^")} 378 | } 379 | if (hasYuan || !xs_str) { 380 | zs_str += CL.call(this, _int, options) + this.m_u.charAt(0); 381 | } 382 | if(!options.forceZheng) { 383 | zs_str += result.decimal ? "" : this.m_z; 384 | }else if(xs_str == '' || xs_str.charAt(xs_str.length-1) !== this.m_u[2]){ 385 | xs_str += this.m_z; 386 | } 387 | // if(result.minus) t_str += this.ch_f; 388 | if(options.forceZheng); 389 | } 390 | return t_str + zs_str + xs_str; 391 | } 392 | 393 | var src = { 394 | CL: CL, 395 | unCL: unCL, 396 | toMoney: toMoney 397 | }; 398 | 399 | function getNzhObjByLang(lang_s, lang_b) { 400 | return { 401 | encodeS: function (num, options) { 402 | options = utils.extend({ ww: true, tenMin: true }, options); 403 | return src.CL.call(lang_s, num, options); 404 | }, 405 | encodeB: function (num, options) { 406 | options = utils.extend({ ww: true }, options); 407 | return src.CL.call(lang_b, num, options); 408 | }, 409 | decodeS: function () { 410 | return src.unCL.apply(lang_s, arguments); 411 | }, 412 | decodeB: function () { 413 | return src.unCL.apply(lang_b, arguments); 414 | }, 415 | toMoney: function (num, options) { 416 | options = utils.extend({ ww: true }, options); 417 | return src.toMoney.call(lang_b, num, options); 418 | } 419 | } 420 | } 421 | var autoGet = getNzhObjByLang; 422 | 423 | var cn_s = { 424 | ch: '零一二三四五六七八九' 425 | ,ch_u: '个十百千万亿' 426 | ,ch_f: '负' 427 | ,ch_d: '点' 428 | }; 429 | 430 | var cn_b = { 431 | ch: '零壹贰叁肆伍陆柒捌玖' 432 | ,ch_u: '个拾佰仟万亿' 433 | ,ch_f: '负' 434 | ,ch_d: '点' 435 | ,m_t: '人民币' 436 | ,m_z: '整' 437 | ,m_u: '元角分' 438 | }; 439 | 440 | var hk_s = { 441 | ch: '零一二三四五六七八九' 442 | ,ch_u: '個十百千萬億' 443 | ,ch_f: '負' 444 | ,ch_d: '點' 445 | }; 446 | 447 | var hk_b = { 448 | ch: '零壹貳參肆伍陸柒捌玖' 449 | ,ch_u: '個拾佰仟萬億' 450 | ,ch_f: '負' 451 | ,ch_d: '點' 452 | ,m_t: '$' 453 | ,m_z: '整' 454 | ,m_u: '圓角分' 455 | }; 456 | 457 | var langs = { 458 | s:cn_s, 459 | b:cn_b, 460 | hk_s:hk_s, 461 | hk_b:hk_b 462 | }; 463 | var Nzh = function(lang){ 464 | this.lang = lang; 465 | this.encode = function(){return src.CL.apply(lang,arguments)}; 466 | this.decode = function(){return src.unCL.apply(lang,arguments)}; 467 | this.toMoney = function(){return src.toMoney.apply(lang,arguments)}; 468 | }; 469 | Nzh.langs = langs; 470 | Nzh.cn = autoGet(langs.s,langs.b); 471 | Nzh.hk = autoGet(langs.hk_s,langs.hk_b); 472 | var nzh = Nzh; 473 | 474 | return nzh; 475 | 476 | }))); 477 | -------------------------------------------------------------------------------- /dist/nzh.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * nzh v1.0.14 3 | * Homepage http://cnwhy.github.io/nzh 4 | * License BSD-2-Clause 5 | */ 6 | !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Nzh=e()}(this,function(){"use strict";function t(t,e){var n=i.getNumbResult(t);if(!n)return t;e=e||{};var r=this.ch,h=this.ch_u,c=this.ch_f||"",u=this.ch_d||".",a=r.charAt(0),o=n.int,s=n.decimal,l=n.minus,f="",g="",p=l?c:"";if(s){s=i.clearZero(s,"0","$");for(var d=0;d1?arguments[1]:e.tenMin,l=n.length;if(1==l)return r.charAt(+n);if(l<=4)for(var f=0,g=l;g--;){var p=+n.charAt(f);o+=s&&2==l&&0==f&&1==p?"":r.charAt(p),o+=p&&g?h.charAt(g):"",f++}else{for(var d=n.length/4>>0,_=n.length%4;0==_||!h.charAt(3+d);)_+=4,d--;var m=n.substr(0,_),A=n.substr(_);o=t(m,s)+h.charAt(3+d)+("0"==A.charAt(0)?a:"")+t(A,A.length>4&&s)}return o=i.clearZero(o,a)}(o),e.ww&&h.length>5){var _=h.charAt(4),m=h.charAt(5),A=f.lastIndexOf(m);~A&&(f=f.substring(0,A).replace(new RegExp(m,"g"),_+_)+f.substring(A))}return p+f+g}function e(t,e){t=t.toString();var n=t.split(this.ch_d),r=n[0].replace(this.ch_f,""),h=n[1],c=!!~n[0].indexOf(this.ch_f),u=this.ch_u.charAt(1),a=this.ch_u.charAt(4),o=this.ch_u.charAt(5);r=r.replace(new RegExp(a+"{2}(?!"+a+")","g"),o);for(var s=r.split(""),l=0,f=0,g=[],p=[],d=[],_=0;_0&&d.unshift(A);else if(~(v=this.ch_u.indexOf(m))){var y=i.getDigit(v);l>v?(i.unshiftZero(d,y),i.centerArray(p,d)):v>=f?(0==_&&(d=[1]),i.centerArray(g,p,d),g.length>0&&i.unshiftZero(g,y),f=v):(0==d.length&&u==m&&(d=[1]),i.centerArray(p,d),i.unshiftZero(p,i.getDigit(v)),l=v)}}i.centerArray(g,p,d).reverse(),0==g.length&&g.push(0);var x=0;if(h){g.push("."),x="0.";for(var _=0;_0){var c=i.substr(0,h);c=c.length2){var r=[].slice.call(arguments,2);r.unshift(e),t.apply(null,r)}return e};var h=e.hasAttr=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)};e.extend=function(t){for(var e,n=arguments[0]||{},r=Array.prototype.slice.call(arguments,1),i=0;i=5?4*(t-4)+4:t},e.unshiftZero=function(t,e){if(null==e&&(e=1),!(e<=0))for(;e--;)t.unshift(0)},e.clearZero=function(t,e,n){if(null==t)return"";var r=~"*.?+$^[](){}|\\/".indexOf(e)?"\\"+e:e,i=new RegExp("^"+r+"+"),h=new RegExp(r+"+$"),c=new RegExp(r+"{2}","g");return t=t.toString(),"^"==n&&(t=t.replace(i,"")),n&&"$"!=n||(t=t.replace(h,"")),n&&"nto1"!=n||(t=t.replace(c,e)),t}}),h=(i.e2ten,i.getNumbResult,i.centerArray,i.hasAttr,i.extend,i.getDigit,i.unshiftZero,i.clearZero,{CL:t,unCL:e,toMoney:n}),c=r,u={ch:"零一二三四五六七八九",ch_u:"个十百千万亿",ch_f:"负",ch_d:"点"},a={ch:"零壹贰叁肆伍陆柒捌玖",ch_u:"个拾佰仟万亿",ch_f:"负",ch_d:"点",m_t:"人民币",m_z:"整",m_u:"元角分"},o={ch:"零一二三四五六七八九",ch_u:"個十百千萬億",ch_f:"負",ch_d:"點"},s={ch:"零壹貳參肆伍陸柒捌玖",ch_u:"個拾佰仟萬億",ch_f:"負",ch_d:"點",m_t:"$",m_z:"整",m_u:"圓角分"},l={s:u,b:a,hk_s:o,hk_b:s},f=function(t){this.lang=t,this.encode=function(){return h.CL.apply(t,arguments)},this.decode=function(){return h.unCL.apply(t,arguments)},this.toMoney=function(){return h.toMoney.apply(t,arguments)}};return f.langs=l,f.cn=c(l.s,l.b),f.hk=c(l.hk_s,l.hk_b),f}); -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cnwhy/nzh/71f536cd4ef1cb37bc68cdc3a45b3ea61fcc7153/docs/.nojekyll -------------------------------------------------------------------------------- /docs/_sidebar.md: -------------------------------------------------------------------------------- 1 | * [Nzh](/) 2 | * [试一试](/demo) 3 | -------------------------------------------------------------------------------- /docs/demo.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | nzh - 数字转中文,大写,金额 6 | 7 | 8 | 9 | 10 | 18 | 19 |
20 | 21 | 32 | 33 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var path = require("path"); 2 | var gulp = require("gulp"); 3 | var mocha = require("gulp-mocha"); 4 | var mochaPhantomjs = require("gulp-mocha-phantomjs"); 5 | var browserify = require("gulp-browserify"); 6 | var uglify = require("gulp-uglify"); 7 | var rename = require("gulp-rename"); 8 | var header = require("gulp-header"); 9 | 10 | var rollup = require("rollup"); 11 | var commonjs = require("rollup-plugin-commonjs"); 12 | var resolve = require("rollup-plugin-node-resolve"); 13 | 14 | 15 | // var istanbul = require("gulp-istanbul"); 16 | var package = require("./package.json"); 17 | var banner = 18 | '/*!\n' + 19 | ' * ' + package.name + ' v' + package.version + '\n' + 20 | ' * Homepage ' + package.homepage + '\n' + 21 | ' * License ' + package.license + '\n' + 22 | ' */\n' 23 | var outputDir = 'dist/' 24 | 25 | gulp.task('build', ['test-server','rollup','min'], function () { 26 | 27 | // return gulp.src('./browser-source/*.js') 28 | // .pipe(browserify()) 29 | // .pipe(header(banner)) 30 | // .pipe(gulp.dest('./dist')) 31 | // .pipe(uglify()) 32 | // .pipe(header(banner)) 33 | // .pipe(rename({ 34 | // suffix:".min" 35 | // })) 36 | // .pipe(gulp.dest('./dist')); 37 | 38 | // return rollup.rollup({ 39 | // input: './nzh.js', 40 | // plugins: [ 41 | // resolve(), 42 | // commonjs() 43 | // ] 44 | // }).then(function (bundle) { 45 | // return bundle.write({ 46 | // file: './dist1/nzh.js', 47 | // format: 'umd', 48 | // name: 'Nzh', 49 | // banner: banner, 50 | // sourcemap: false 51 | // }) 52 | // }) 53 | }) 54 | 55 | function runRollup(input, output) { 56 | var inputopt = { 57 | // input: './nzh.js', 58 | plugins: [ 59 | resolve(), 60 | commonjs() 61 | ] 62 | } 63 | var outputopt = { 64 | // file: './dist/nzh.js', 65 | format: 'umd', 66 | name: 'Nzh', 67 | banner: banner, 68 | sourcemap: false 69 | } 70 | return rollup.rollup(Object.assign({},inputopt,{ 71 | input: input 72 | })).then(function (bundle) { 73 | return bundle.write(Object.assign({},outputopt,{ 74 | file: output, 75 | })) 76 | }) 77 | } 78 | 79 | gulp.task('rollup', function () { 80 | return Promise.all([ 81 | runRollup('./nzh.js',outputDir + 'nzh.js'), 82 | runRollup('./cn.js',outputDir + 'nzh.cn.js'), 83 | runRollup('./hk.js',outputDir + 'nzh.hk.js'), 84 | ]) 85 | }) 86 | 87 | gulp.task('min',['rollup'],function () { 88 | return gulp.src(['dist/!(*.min).js']) 89 | .pipe(uglify()) 90 | .pipe(header(banner)) 91 | .pipe(rename({ 92 | suffix:".min" 93 | })) 94 | .pipe(gulp.dest(outputDir)); 95 | }) 96 | 97 | 98 | // gulp.task('pre-test', function () { 99 | // return gulp.src(['src/**/*.js']) 100 | // // Covering files 101 | // .pipe(istanbul()) 102 | // // Force `require` to return covered files 103 | // .pipe(istanbul.hookRequire()); 104 | // }); 105 | 106 | // gulp.task('test', ['pre-test'], function () { 107 | // return gulp.src('test/mocha_*.js', {read: false}) 108 | // .pipe(mocha({reporter: 'dot'})) 109 | // // Creating the reports after tests ran 110 | // .pipe(istanbul.writeReports()) 111 | // // Enforce a coverage of at least 90% 112 | // .pipe(istanbul.enforceThresholds({ thresholds: { global: 90 } })); 113 | // }); 114 | 115 | gulp.task('test', ['test-server', 'test-browser']) 116 | 117 | gulp.task('test-server', function () { 118 | return gulp.src('test/test_mocha.js', { read: false }) 119 | .pipe(mocha({ reporter: 'dot' })) 120 | }); 121 | 122 | gulp.task('output-testjs-browser', ['test-server'], function () { 123 | return gulp.src('test/test_mocha.js') 124 | .pipe(browserify({ insertGlobals: true })) 125 | .pipe(rename({ 126 | basename: "tests" 127 | })) 128 | .pipe(gulp.dest('test/browser')); 129 | }) 130 | 131 | gulp.task('test-browser', ['output-testjs-browser', 'build'], function () { 132 | return gulp.src('test/browser/test.html') 133 | .pipe(mochaPhantomjs({ reporter: 'dot' })) 134 | }) 135 | 136 | gulp.task('test-docs', ['build'], function () { 137 | 138 | }) 139 | 140 | gulp.task('default', ['build', 'test']); -------------------------------------------------------------------------------- /hk.js: -------------------------------------------------------------------------------- 1 | var getNzhObjByLang = require("./src/autoGet"); 2 | var langs = { 3 | s: require("./src/langs/hk_s"), 4 | b: require("./src/langs/hk_b"), 5 | } 6 | module.exports = getNzhObjByLang(langs.s, langs.b); -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /lib/nzh.cn.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * nzh v1.0.9 3 | * Homepage http://cnwhy.github.io/nzh 4 | * License BSD-2-Clause 5 | */ 6 | 7 | function createCommonjsModule(fn, module) { 8 | return module = { exports: {} }, fn(module, module.exports), module.exports; 9 | } 10 | 11 | var utils = createCommonjsModule(function (module, exports) { 12 | var REG_NUMBER = /^([+-])?0*(\d+)(\.(\d+))?$/; 13 | var REG_E = /^([+-])?0*(\d+)(\.(\d+))?e(([+-])?(\d+))$/i; 14 | 15 | /** 16 | * 科学计数法转十进制 17 | * 18 | * @param {string} num 科学记数法字符串 19 | * @returns string 20 | */ 21 | var e2ten = exports.e2ten = function (num) { 22 | var result = REG_E.exec(num.toString()); 23 | if (!result) return num; 24 | var zs = result[2] 25 | , xs = result[4] || "" 26 | , e = result[5] ? +result[5] : 0; 27 | if (e > 0) { 28 | var _zs = xs.substr(0, e); 29 | _zs = _zs.length < e ? _zs + new Array(e - _zs.length + 1).join("0") : _zs; 30 | xs = xs.substr(e); 31 | zs += _zs; 32 | } else { 33 | e = -e; 34 | var s_start = zs.length - e; 35 | s_start = s_start < 0 ? 0 : s_start; 36 | var _xs = zs.substr(s_start, e); 37 | _xs = _xs.length < e ? new Array(e - _xs.length + 1).join("0") + _xs : _xs; 38 | zs = zs.substring(0, s_start); 39 | xs = _xs + xs; 40 | } 41 | zs = zs == "" ? "0" : zs; 42 | return (result[1] == "-" ? "-" : "") + zs + (xs ? "." + xs : ""); 43 | }; 44 | 45 | /** 46 | * 分析数字字符串 47 | * 48 | * @param {string} num NumberString 49 | * @returns object 50 | */ 51 | exports.getNumbResult = function (num) { 52 | var result = REG_NUMBER.exec(num.toString()); 53 | if (!result && REG_E.test(num.toString())) { 54 | result = REG_NUMBER.exec(e2ten(num.toString())); 55 | } 56 | if (result) { 57 | return { 58 | int: result[2], 59 | decimal: result[4], 60 | minus: result[1] == "-", 61 | num: result.slice(1, 3).join('') 62 | } 63 | } 64 | }; 65 | 66 | /** 67 | * 数组归一 (按索引覆盖合并数组,并清空被合并的数组) 68 | * 69 | * @param {array} baseArray 基础数组 70 | * @param {...array} array1 71 | * @returns array 72 | */ 73 | exports.centerArray = function centerArray(baseArray, array1 /*[, array2[, ...[, arrayN]]]*/) { 74 | baseArray.splice.apply(baseArray, [0, array1.length].concat(array1.splice(0, array1.length))); 75 | if (arguments.length > 2) { 76 | var r = [].slice.call(arguments, 2); 77 | r.unshift(baseArray); 78 | centerArray.apply(null, r); 79 | } 80 | return baseArray; 81 | }; 82 | 83 | /** 84 | * 检查对像属性 (非原型链) 85 | * 86 | * @param {object} obj 87 | * @param {string} key 88 | * @returns 89 | */ 90 | var hasAttr = exports.hasAttr = function (obj, key) { 91 | return Object.prototype.hasOwnProperty.call(obj, key); 92 | }; 93 | 94 | /** 95 | * 扩展对像(浅复制) 96 | * 97 | * @param {object} obj 98 | * @param {object} obj1 99 | * @returns 100 | */ 101 | exports.extend = function (obj) { 102 | var name 103 | , target = arguments[0] || {}; 104 | var objs = Array.prototype.slice.call(arguments, 1); 105 | 106 | for (var i = 0; i < objs.length; i++) { 107 | var _obj = objs[i]; 108 | for (name in _obj) { 109 | if (hasAttr(_obj, name)) { 110 | target[name] = _obj[name]; 111 | } 112 | } 113 | } 114 | return target; 115 | }; 116 | 117 | 118 | /** 119 | * 获取真实数位 120 | * 121 | * @param {number} index 中文单位的索引 122 | */ 123 | exports.getDigit = function (index) { 124 | return index >= 5 ? (index - 4) * 4 + 4 : index; 125 | }; 126 | 127 | /** 128 | * 往数组头部插入0 129 | * 130 | * @param {array} arr 131 | * @param {number} n 132 | */ 133 | exports.unshiftZero = function (arr, n) { 134 | if (n == null) n = 1; 135 | if (n <= 0) return; 136 | for (; n--;) arr.unshift(0); 137 | }; 138 | 139 | /** 140 | * 清理多余"零" 141 | * 142 | * @param {any} str 143 | * @param {any} zero "零"字符 144 | * @param {any} type 清理模式 ^ - 开头, $ - 结尾, nto1 - 多个连续变一个 145 | * @returns 146 | */ 147 | exports.clearZero = function (str, zero, type) { 148 | if (str == null) return ""; 149 | var reg0 = ~"*.?+$^[](){}|\\/".indexOf(zero) ? "\\" + zero : zero; 150 | var arg_s = new RegExp("^" + reg0 + "+") 151 | , arg_e = new RegExp(reg0 + "+$") 152 | , arg_d = new RegExp(reg0 + "{2}", "g"); 153 | str = str.toString(); 154 | if (type == "^") { 155 | str = str.replace(arg_s, ""); 156 | } 157 | if (!type || type == "$") { 158 | str = str.replace(arg_e, ""); 159 | } 160 | if (!type || type == "nto1") { 161 | str = str.replace(arg_d, zero); 162 | } 163 | return str; 164 | }; 165 | }); 166 | var utils_1 = utils.e2ten; 167 | var utils_2 = utils.getNumbResult; 168 | var utils_3 = utils.centerArray; 169 | var utils_4 = utils.hasAttr; 170 | var utils_5 = utils.extend; 171 | var utils_6 = utils.getDigit; 172 | var utils_7 = utils.unshiftZero; 173 | var utils_8 = utils.clearZero; 174 | 175 | /** 176 | * 阿拉伯数字转中文数字 177 | * 178 | * @param {String} num 阿拉伯数字/字符串 , 科学记数法字符串 179 | * @param {Object} opration 转换配置 180 | * { 181 | * ww: {万万化单位 | false} 182 | * tenMin: {十的口语化 | false} 183 | * } 184 | * @returns String 185 | */ 186 | function CL(num, options) { 187 | var result = utils.getNumbResult(num); 188 | if (!result) { 189 | return num; 190 | } 191 | options = options ? options : {}; 192 | var ch = this.ch //数字 193 | , ch_u = this.ch_u //单位 194 | , ch_f = this.ch_f || "" //负 195 | , ch_d = this.ch_d || "." //点 196 | , n0 = ch.charAt(0); //零 197 | var _int = result.int //整数部分 198 | , _decimal = result.decimal //小数部分 199 | , _minus = result.minus; //负数标识 200 | var int = "" 201 | , dicimal = "" 202 | , minus = _minus ? ch_f : ''; //符号位 203 | var encodeInt = function encodeInt(_int, _m, _dg) { 204 | _int = utils.getNumbResult(_int).int; 205 | var int = "" 206 | , tenm = arguments.length > 1 ? arguments[1] : options.tenMin 207 | , _length = _int.length; 208 | //一位整数 209 | if (_length == 1) return ch.charAt(+_int); 210 | if (_length <= 4) { //四位及以下 211 | for (var i = 0, n = _length; n--;) { 212 | var _num = +_int.charAt(i); 213 | int += (tenm && _length == 2 && i == 0 && _num == 1) ? "" : ch.charAt(_num); 214 | int += (_num && n ? ch_u.charAt(n) : ''); 215 | i++; 216 | } 217 | } else { //大数递归 218 | var d = _int.length / 4 >> 0 219 | , y = _int.length % 4; 220 | //"兆","京"等单位处理 221 | while (y == 0 || !ch_u.charAt(3 + d)) { 222 | y += 4; 223 | d--; 224 | } 225 | var _maxLeft = _int.substr(0, y), //最大单位前的数字 226 | _other = _int.substr(y); //剩余数字 227 | 228 | int = encodeInt(_maxLeft, tenm) + ch_u.charAt(3 + d) 229 | + (_other.charAt(0) == '0' ? n0 : '') //单位后有0则加零 230 | + encodeInt(_other, _other.length > 4 ? tenm : false); 231 | } 232 | int = utils.clearZero(int, n0); //修整零 233 | return int; 234 | }; 235 | 236 | //转换小数部分 237 | if (_decimal) { 238 | _decimal = utils.clearZero(_decimal, "0", "$"); //去除尾部0 239 | for (var x = 0; x < _decimal.length; x++) { 240 | dicimal += ch.charAt(+_decimal.charAt(x)); 241 | } 242 | dicimal = dicimal ? ch_d + dicimal : ""; 243 | } 244 | 245 | //转换整数部分 246 | int = encodeInt(_int); //转换整数 247 | 248 | //超级大数的万万化 249 | if (options.ww && ch_u.length > 5) { 250 | var dw_w = ch_u.charAt(4) 251 | , dw_y = ch_u.charAt(5); 252 | var lasty = int.lastIndexOf(dw_y); 253 | if (~lasty) { 254 | int = int.substring(0, lasty).replace(new RegExp(dw_y, 'g'), dw_w + dw_w) + int.substring(lasty); 255 | } 256 | } 257 | return minus + int + dicimal; 258 | } 259 | 260 | /** 261 | * 中文数字转阿拉伯数字 262 | * 263 | * @param {string} cnnumb 中文数字字符串 264 | * @returns Number 265 | */ 266 | function unCL(cnnumb) { 267 | cnnumb = cnnumb.toString(); 268 | var result = cnnumb.split(this.ch_d); 269 | var _int = result[0].replace(this.ch_f, "") 270 | , _decimal = result[1] 271 | , _minus = !!~result[0].indexOf(this.ch_f); 272 | 273 | var dw_s = this.ch_u.charAt(1) 274 | , dw_w = this.ch_u.charAt(4) 275 | , dw_y = this.ch_u.charAt(5); 276 | 277 | _int = _int.replace(new RegExp(dw_w + "{2}", "g"), dw_y); 278 | 279 | var cnarr = _int.split(''); 280 | var dw = 0, maxdw = 0; 281 | var rnum_a = [], num_a = [], _num_a = []; 282 | for (var i = 0; i < cnarr.length; i++) { 283 | var chr = cnarr[i]; 284 | var n = 0, u = 0; 285 | if (~(n = this.ch.indexOf(chr))) { 286 | //_num = _num*10 + n; 287 | if (n > 0) _num_a.unshift(n); 288 | //_num_a.unshift(n); 289 | } else if (~(u = this.ch_u.indexOf(chr))) { 290 | var digit = utils.getDigit(u); 291 | if (dw > u) {//正常情况 292 | utils.unshiftZero(_num_a, digit); 293 | utils.centerArray(num_a, _num_a); 294 | } else if (u >= maxdw) {//后跟大单位 295 | if (i == 0) _num_a = [1]; 296 | utils.centerArray(rnum_a, num_a, _num_a); 297 | if (rnum_a.length > 0) utils.unshiftZero(rnum_a, digit); 298 | maxdw = u; 299 | } else { 300 | if (_num_a.length == 0 && dw_s == chr) _num_a = [1]; 301 | utils.centerArray(num_a, _num_a); 302 | utils.unshiftZero(num_a, utils.getDigit(u)); 303 | dw = u; 304 | } 305 | } 306 | } 307 | utils.centerArray(rnum_a, num_a, _num_a).reverse(); 308 | if (rnum_a.length == 0) rnum_a.push(0); 309 | var decimal = 0; 310 | if (_decimal) { 311 | rnum_a.push('.'); 312 | decimal = '0.'; 313 | for (var i = 0; i < _decimal.length; i++) { 314 | decimal += this.ch.indexOf(_decimal.charAt(i)); 315 | rnum_a.push(this.ch.indexOf(_decimal.charAt(i))); 316 | } 317 | decimal = +decimal; 318 | 319 | } 320 | if (_minus) rnum_a.unshift('-'); 321 | return parseFloat(rnum_a.join('')); 322 | } 323 | 324 | /** 325 | * 阿拉伯数字转金额 326 | * 327 | * @param {String} num 阿拉伯数字/字符串 , 科学记数法字符串 328 | * @param {Object} options 转换配置 329 | * { 330 | * ww:{万万化开关 | true}, 331 | * unOmitYuan: {整数为0时不省略元| false}, 332 | * complete:{完整金额格式 | false}, 333 | * outSymbol:{是否输出金额符号 | true} 334 | * } 335 | * @returns String 336 | */ 337 | function toMoney(num, options) { 338 | var def = { ww: true, complete: false, outSymbol: true, unOmitYuan: false }; 339 | var result = utils.getNumbResult(num); 340 | var ch_0 = this.ch.charAt(0); 341 | options = typeof options == "object" ? options : {}; 342 | if (!result) { return num; } 343 | options = utils.extend(def, options); 344 | 345 | var _int = result.int 346 | , _decimal = result.decimal || ""; 347 | var t_str = options.outSymbol ? this.m_t : "" 348 | , zs_str = result.minus ? this.ch_f : "" 349 | , xs_str = ""; 350 | if (options.complete) { 351 | for (var i = 1; i < this.m_u.length; i++) { 352 | xs_str += CL.call(this, _decimal.charAt(i - 1) || "0") + this.m_u.charAt(i); 353 | } 354 | zs_str += CL.call(this, _int, options) + this.m_u.charAt(0); 355 | } else { 356 | var hasYuan = options.unOmitYuan || _int !== '0'; 357 | _decimal = _decimal.substr(0, this.m_u.length-1); 358 | _decimal = utils.clearZero(_decimal, "0", "$"); //去除尾部的0 359 | if (_decimal) { 360 | var mark_0; 361 | for (var i = 0; i < this.m_u.length - 1; i++) { 362 | if (_decimal.charAt(i) && _decimal.charAt(i) != "0") { 363 | xs_str += CL.call(this, _decimal.charAt(i)) + this.m_u.charAt(i + 1); 364 | mark_0 = false; 365 | } 366 | if (_decimal.charAt(i) === "0" && !mark_0) { 367 | if (i != 0 || _int !== "0") xs_str += ch_0; //当没有输出元时,小数前无需加零 368 | mark_0 = true; 369 | } 370 | } 371 | //if(_num == "0"){xs_str = utils.clearZero(xs_str,ch_0,"^")} 372 | } 373 | if (hasYuan || !xs_str) { 374 | zs_str += CL.call(this, _int, options) + this.m_u.charAt(0) + (result.decimal ? "" : this.m_z); 375 | } 376 | // if(result.minus) t_str += this.ch_f; 377 | } 378 | return t_str + zs_str + xs_str; 379 | } 380 | 381 | var src = { 382 | CL: CL, 383 | unCL: unCL, 384 | toMoney: toMoney 385 | }; 386 | 387 | function getNzhObjByLang(lang_s, lang_b) { 388 | return { 389 | encodeS: function (num, options) { 390 | options = utils.extend({ ww: true, tenMin: true }, options); 391 | return src.CL.call(lang_s, num, options); 392 | }, 393 | encodeB: function (num, options) { 394 | options = utils.extend({ ww: true }, options); 395 | return src.CL.call(lang_b, num, options); 396 | }, 397 | decodeS: function () { 398 | return src.unCL.apply(lang_s, arguments); 399 | }, 400 | decodeB: function () { 401 | return src.unCL.apply(lang_b, arguments); 402 | }, 403 | toMoney: function (num, options) { 404 | options = utils.extend({ ww: true }, options); 405 | return src.toMoney.call(lang_b, num, options); 406 | } 407 | } 408 | } 409 | var autoGet = getNzhObjByLang; 410 | 411 | var cn_s = { 412 | ch: '零一二三四五六七八九' 413 | ,ch_u: '个十百千万亿' 414 | ,ch_f: '负' 415 | ,ch_d: '点' 416 | }; 417 | 418 | var cn_b = { 419 | ch: '零壹贰叁肆伍陆柒捌玖' 420 | ,ch_u: '个拾佰仟万亿' 421 | ,ch_f: '负' 422 | ,ch_d: '点' 423 | ,m_t: '人民币' 424 | ,m_z: '整' 425 | ,m_u: '元角分' 426 | }; 427 | 428 | var langs = { 429 | s: cn_s, 430 | b: cn_b, 431 | }; 432 | var cn = autoGet(langs.s, langs.b); 433 | 434 | export default cn; 435 | -------------------------------------------------------------------------------- /lib/nzh.hk.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * nzh v1.0.9 3 | * Homepage http://cnwhy.github.io/nzh 4 | * License BSD-2-Clause 5 | */ 6 | 7 | function createCommonjsModule(fn, module) { 8 | return module = { exports: {} }, fn(module, module.exports), module.exports; 9 | } 10 | 11 | var utils = createCommonjsModule(function (module, exports) { 12 | var REG_NUMBER = /^([+-])?0*(\d+)(\.(\d+))?$/; 13 | var REG_E = /^([+-])?0*(\d+)(\.(\d+))?e(([+-])?(\d+))$/i; 14 | 15 | /** 16 | * 科学计数法转十进制 17 | * 18 | * @param {string} num 科学记数法字符串 19 | * @returns string 20 | */ 21 | var e2ten = exports.e2ten = function (num) { 22 | var result = REG_E.exec(num.toString()); 23 | if (!result) return num; 24 | var zs = result[2] 25 | , xs = result[4] || "" 26 | , e = result[5] ? +result[5] : 0; 27 | if (e > 0) { 28 | var _zs = xs.substr(0, e); 29 | _zs = _zs.length < e ? _zs + new Array(e - _zs.length + 1).join("0") : _zs; 30 | xs = xs.substr(e); 31 | zs += _zs; 32 | } else { 33 | e = -e; 34 | var s_start = zs.length - e; 35 | s_start = s_start < 0 ? 0 : s_start; 36 | var _xs = zs.substr(s_start, e); 37 | _xs = _xs.length < e ? new Array(e - _xs.length + 1).join("0") + _xs : _xs; 38 | zs = zs.substring(0, s_start); 39 | xs = _xs + xs; 40 | } 41 | zs = zs == "" ? "0" : zs; 42 | return (result[1] == "-" ? "-" : "") + zs + (xs ? "." + xs : ""); 43 | }; 44 | 45 | /** 46 | * 分析数字字符串 47 | * 48 | * @param {string} num NumberString 49 | * @returns object 50 | */ 51 | exports.getNumbResult = function (num) { 52 | var result = REG_NUMBER.exec(num.toString()); 53 | if (!result && REG_E.test(num.toString())) { 54 | result = REG_NUMBER.exec(e2ten(num.toString())); 55 | } 56 | if (result) { 57 | return { 58 | int: result[2], 59 | decimal: result[4], 60 | minus: result[1] == "-", 61 | num: result.slice(1, 3).join('') 62 | } 63 | } 64 | }; 65 | 66 | /** 67 | * 数组归一 (按索引覆盖合并数组,并清空被合并的数组) 68 | * 69 | * @param {array} baseArray 基础数组 70 | * @param {...array} array1 71 | * @returns array 72 | */ 73 | exports.centerArray = function centerArray(baseArray, array1 /*[, array2[, ...[, arrayN]]]*/) { 74 | baseArray.splice.apply(baseArray, [0, array1.length].concat(array1.splice(0, array1.length))); 75 | if (arguments.length > 2) { 76 | var r = [].slice.call(arguments, 2); 77 | r.unshift(baseArray); 78 | centerArray.apply(null, r); 79 | } 80 | return baseArray; 81 | }; 82 | 83 | /** 84 | * 检查对像属性 (非原型链) 85 | * 86 | * @param {object} obj 87 | * @param {string} key 88 | * @returns 89 | */ 90 | var hasAttr = exports.hasAttr = function (obj, key) { 91 | return Object.prototype.hasOwnProperty.call(obj, key); 92 | }; 93 | 94 | /** 95 | * 扩展对像(浅复制) 96 | * 97 | * @param {object} obj 98 | * @param {object} obj1 99 | * @returns 100 | */ 101 | exports.extend = function (obj) { 102 | var name 103 | , target = arguments[0] || {}; 104 | var objs = Array.prototype.slice.call(arguments, 1); 105 | 106 | for (var i = 0; i < objs.length; i++) { 107 | var _obj = objs[i]; 108 | for (name in _obj) { 109 | if (hasAttr(_obj, name)) { 110 | target[name] = _obj[name]; 111 | } 112 | } 113 | } 114 | return target; 115 | }; 116 | 117 | 118 | /** 119 | * 获取真实数位 120 | * 121 | * @param {number} index 中文单位的索引 122 | */ 123 | exports.getDigit = function (index) { 124 | return index >= 5 ? (index - 4) * 4 + 4 : index; 125 | }; 126 | 127 | /** 128 | * 往数组头部插入0 129 | * 130 | * @param {array} arr 131 | * @param {number} n 132 | */ 133 | exports.unshiftZero = function (arr, n) { 134 | if (n == null) n = 1; 135 | if (n <= 0) return; 136 | for (; n--;) arr.unshift(0); 137 | }; 138 | 139 | /** 140 | * 清理多余"零" 141 | * 142 | * @param {any} str 143 | * @param {any} zero "零"字符 144 | * @param {any} type 清理模式 ^ - 开头, $ - 结尾, nto1 - 多个连续变一个 145 | * @returns 146 | */ 147 | exports.clearZero = function (str, zero, type) { 148 | if (str == null) return ""; 149 | var reg0 = ~"*.?+$^[](){}|\\/".indexOf(zero) ? "\\" + zero : zero; 150 | var arg_s = new RegExp("^" + reg0 + "+") 151 | , arg_e = new RegExp(reg0 + "+$") 152 | , arg_d = new RegExp(reg0 + "{2}", "g"); 153 | str = str.toString(); 154 | if (type == "^") { 155 | str = str.replace(arg_s, ""); 156 | } 157 | if (!type || type == "$") { 158 | str = str.replace(arg_e, ""); 159 | } 160 | if (!type || type == "nto1") { 161 | str = str.replace(arg_d, zero); 162 | } 163 | return str; 164 | }; 165 | }); 166 | var utils_1 = utils.e2ten; 167 | var utils_2 = utils.getNumbResult; 168 | var utils_3 = utils.centerArray; 169 | var utils_4 = utils.hasAttr; 170 | var utils_5 = utils.extend; 171 | var utils_6 = utils.getDigit; 172 | var utils_7 = utils.unshiftZero; 173 | var utils_8 = utils.clearZero; 174 | 175 | /** 176 | * 阿拉伯数字转中文数字 177 | * 178 | * @param {String} num 阿拉伯数字/字符串 , 科学记数法字符串 179 | * @param {Object} opration 转换配置 180 | * { 181 | * ww: {万万化单位 | false} 182 | * tenMin: {十的口语化 | false} 183 | * } 184 | * @returns String 185 | */ 186 | function CL(num, options) { 187 | var result = utils.getNumbResult(num); 188 | if (!result) { 189 | return num; 190 | } 191 | options = options ? options : {}; 192 | var ch = this.ch //数字 193 | , ch_u = this.ch_u //单位 194 | , ch_f = this.ch_f || "" //负 195 | , ch_d = this.ch_d || "." //点 196 | , n0 = ch.charAt(0); //零 197 | var _int = result.int //整数部分 198 | , _decimal = result.decimal //小数部分 199 | , _minus = result.minus; //负数标识 200 | var int = "" 201 | , dicimal = "" 202 | , minus = _minus ? ch_f : ''; //符号位 203 | var encodeInt = function encodeInt(_int, _m, _dg) { 204 | _int = utils.getNumbResult(_int).int; 205 | var int = "" 206 | , tenm = arguments.length > 1 ? arguments[1] : options.tenMin 207 | , _length = _int.length; 208 | //一位整数 209 | if (_length == 1) return ch.charAt(+_int); 210 | if (_length <= 4) { //四位及以下 211 | for (var i = 0, n = _length; n--;) { 212 | var _num = +_int.charAt(i); 213 | int += (tenm && _length == 2 && i == 0 && _num == 1) ? "" : ch.charAt(_num); 214 | int += (_num && n ? ch_u.charAt(n) : ''); 215 | i++; 216 | } 217 | } else { //大数递归 218 | var d = _int.length / 4 >> 0 219 | , y = _int.length % 4; 220 | //"兆","京"等单位处理 221 | while (y == 0 || !ch_u.charAt(3 + d)) { 222 | y += 4; 223 | d--; 224 | } 225 | var _maxLeft = _int.substr(0, y), //最大单位前的数字 226 | _other = _int.substr(y); //剩余数字 227 | 228 | int = encodeInt(_maxLeft, tenm) + ch_u.charAt(3 + d) 229 | + (_other.charAt(0) == '0' ? n0 : '') //单位后有0则加零 230 | + encodeInt(_other, _other.length > 4 ? tenm : false); 231 | } 232 | int = utils.clearZero(int, n0); //修整零 233 | return int; 234 | }; 235 | 236 | //转换小数部分 237 | if (_decimal) { 238 | _decimal = utils.clearZero(_decimal, "0", "$"); //去除尾部0 239 | for (var x = 0; x < _decimal.length; x++) { 240 | dicimal += ch.charAt(+_decimal.charAt(x)); 241 | } 242 | dicimal = dicimal ? ch_d + dicimal : ""; 243 | } 244 | 245 | //转换整数部分 246 | int = encodeInt(_int); //转换整数 247 | 248 | //超级大数的万万化 249 | if (options.ww && ch_u.length > 5) { 250 | var dw_w = ch_u.charAt(4) 251 | , dw_y = ch_u.charAt(5); 252 | var lasty = int.lastIndexOf(dw_y); 253 | if (~lasty) { 254 | int = int.substring(0, lasty).replace(new RegExp(dw_y, 'g'), dw_w + dw_w) + int.substring(lasty); 255 | } 256 | } 257 | return minus + int + dicimal; 258 | } 259 | 260 | /** 261 | * 中文数字转阿拉伯数字 262 | * 263 | * @param {string} cnnumb 中文数字字符串 264 | * @returns Number 265 | */ 266 | function unCL(cnnumb) { 267 | cnnumb = cnnumb.toString(); 268 | var result = cnnumb.split(this.ch_d); 269 | var _int = result[0].replace(this.ch_f, "") 270 | , _decimal = result[1] 271 | , _minus = !!~result[0].indexOf(this.ch_f); 272 | 273 | var dw_s = this.ch_u.charAt(1) 274 | , dw_w = this.ch_u.charAt(4) 275 | , dw_y = this.ch_u.charAt(5); 276 | 277 | _int = _int.replace(new RegExp(dw_w + "{2}", "g"), dw_y); 278 | 279 | var cnarr = _int.split(''); 280 | var dw = 0, maxdw = 0; 281 | var rnum_a = [], num_a = [], _num_a = []; 282 | for (var i = 0; i < cnarr.length; i++) { 283 | var chr = cnarr[i]; 284 | var n = 0, u = 0; 285 | if (~(n = this.ch.indexOf(chr))) { 286 | //_num = _num*10 + n; 287 | if (n > 0) _num_a.unshift(n); 288 | //_num_a.unshift(n); 289 | } else if (~(u = this.ch_u.indexOf(chr))) { 290 | var digit = utils.getDigit(u); 291 | if (dw > u) {//正常情况 292 | utils.unshiftZero(_num_a, digit); 293 | utils.centerArray(num_a, _num_a); 294 | } else if (u >= maxdw) {//后跟大单位 295 | if (i == 0) _num_a = [1]; 296 | utils.centerArray(rnum_a, num_a, _num_a); 297 | if (rnum_a.length > 0) utils.unshiftZero(rnum_a, digit); 298 | maxdw = u; 299 | } else { 300 | if (_num_a.length == 0 && dw_s == chr) _num_a = [1]; 301 | utils.centerArray(num_a, _num_a); 302 | utils.unshiftZero(num_a, utils.getDigit(u)); 303 | dw = u; 304 | } 305 | } 306 | } 307 | utils.centerArray(rnum_a, num_a, _num_a).reverse(); 308 | if (rnum_a.length == 0) rnum_a.push(0); 309 | var decimal = 0; 310 | if (_decimal) { 311 | rnum_a.push('.'); 312 | decimal = '0.'; 313 | for (var i = 0; i < _decimal.length; i++) { 314 | decimal += this.ch.indexOf(_decimal.charAt(i)); 315 | rnum_a.push(this.ch.indexOf(_decimal.charAt(i))); 316 | } 317 | decimal = +decimal; 318 | 319 | } 320 | if (_minus) rnum_a.unshift('-'); 321 | return parseFloat(rnum_a.join('')); 322 | } 323 | 324 | /** 325 | * 阿拉伯数字转金额 326 | * 327 | * @param {String} num 阿拉伯数字/字符串 , 科学记数法字符串 328 | * @param {Object} options 转换配置 329 | * { 330 | * ww:{万万化开关 | true}, 331 | * unOmitYuan: {整数为0时不省略元| false}, 332 | * complete:{完整金额格式 | false}, 333 | * outSymbol:{是否输出金额符号 | true} 334 | * } 335 | * @returns String 336 | */ 337 | function toMoney(num, options) { 338 | var def = { ww: true, complete: false, outSymbol: true, unOmitYuan: false }; 339 | var result = utils.getNumbResult(num); 340 | var ch_0 = this.ch.charAt(0); 341 | options = typeof options == "object" ? options : {}; 342 | if (!result) { return num; } 343 | options = utils.extend(def, options); 344 | 345 | var _int = result.int 346 | , _decimal = result.decimal || ""; 347 | var t_str = options.outSymbol ? this.m_t : "" 348 | , zs_str = result.minus ? this.ch_f : "" 349 | , xs_str = ""; 350 | if (options.complete) { 351 | for (var i = 1; i < this.m_u.length; i++) { 352 | xs_str += CL.call(this, _decimal.charAt(i - 1) || "0") + this.m_u.charAt(i); 353 | } 354 | zs_str += CL.call(this, _int, options) + this.m_u.charAt(0); 355 | } else { 356 | var hasYuan = options.unOmitYuan || _int !== '0'; 357 | _decimal = _decimal.substr(0, this.m_u.length-1); 358 | _decimal = utils.clearZero(_decimal, "0", "$"); //去除尾部的0 359 | if (_decimal) { 360 | var mark_0; 361 | for (var i = 0; i < this.m_u.length - 1; i++) { 362 | if (_decimal.charAt(i) && _decimal.charAt(i) != "0") { 363 | xs_str += CL.call(this, _decimal.charAt(i)) + this.m_u.charAt(i + 1); 364 | mark_0 = false; 365 | } 366 | if (_decimal.charAt(i) === "0" && !mark_0) { 367 | if (i != 0 || _int !== "0") xs_str += ch_0; //当没有输出元时,小数前无需加零 368 | mark_0 = true; 369 | } 370 | } 371 | //if(_num == "0"){xs_str = utils.clearZero(xs_str,ch_0,"^")} 372 | } 373 | if (hasYuan || !xs_str) { 374 | zs_str += CL.call(this, _int, options) + this.m_u.charAt(0) + (result.decimal ? "" : this.m_z); 375 | } 376 | // if(result.minus) t_str += this.ch_f; 377 | } 378 | return t_str + zs_str + xs_str; 379 | } 380 | 381 | var src = { 382 | CL: CL, 383 | unCL: unCL, 384 | toMoney: toMoney 385 | }; 386 | 387 | function getNzhObjByLang(lang_s, lang_b) { 388 | return { 389 | encodeS: function (num, options) { 390 | options = utils.extend({ ww: true, tenMin: true }, options); 391 | return src.CL.call(lang_s, num, options); 392 | }, 393 | encodeB: function (num, options) { 394 | options = utils.extend({ ww: true }, options); 395 | return src.CL.call(lang_b, num, options); 396 | }, 397 | decodeS: function () { 398 | return src.unCL.apply(lang_s, arguments); 399 | }, 400 | decodeB: function () { 401 | return src.unCL.apply(lang_b, arguments); 402 | }, 403 | toMoney: function (num, options) { 404 | options = utils.extend({ ww: true }, options); 405 | return src.toMoney.call(lang_b, num, options); 406 | } 407 | } 408 | } 409 | var autoGet = getNzhObjByLang; 410 | 411 | var hk_s = { 412 | ch: '零一二三四五六七八九' 413 | ,ch_u: '個十百千萬億' 414 | ,ch_f: '負' 415 | ,ch_d: '點' 416 | }; 417 | 418 | var hk_b = { 419 | ch: '零壹貳參肆伍陸柒捌玖' 420 | ,ch_u: '個拾佰仟萬億' 421 | ,ch_f: '負' 422 | ,ch_d: '點' 423 | ,m_t: '$' 424 | ,m_z: '整' 425 | ,m_u: '圓角分' 426 | }; 427 | 428 | var langs = { 429 | s: hk_s, 430 | b: hk_b, 431 | }; 432 | var hk = autoGet(langs.s, langs.b); 433 | 434 | export default hk; 435 | -------------------------------------------------------------------------------- /lib/nzh.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * nzh v1.0.9 3 | * Homepage http://cnwhy.github.io/nzh 4 | * License BSD-2-Clause 5 | */ 6 | 7 | function createCommonjsModule(fn, module) { 8 | return module = { exports: {} }, fn(module, module.exports), module.exports; 9 | } 10 | 11 | var utils = createCommonjsModule(function (module, exports) { 12 | var REG_NUMBER = /^([+-])?0*(\d+)(\.(\d+))?$/; 13 | var REG_E = /^([+-])?0*(\d+)(\.(\d+))?e(([+-])?(\d+))$/i; 14 | 15 | /** 16 | * 科学计数法转十进制 17 | * 18 | * @param {string} num 科学记数法字符串 19 | * @returns string 20 | */ 21 | var e2ten = exports.e2ten = function (num) { 22 | var result = REG_E.exec(num.toString()); 23 | if (!result) return num; 24 | var zs = result[2] 25 | , xs = result[4] || "" 26 | , e = result[5] ? +result[5] : 0; 27 | if (e > 0) { 28 | var _zs = xs.substr(0, e); 29 | _zs = _zs.length < e ? _zs + new Array(e - _zs.length + 1).join("0") : _zs; 30 | xs = xs.substr(e); 31 | zs += _zs; 32 | } else { 33 | e = -e; 34 | var s_start = zs.length - e; 35 | s_start = s_start < 0 ? 0 : s_start; 36 | var _xs = zs.substr(s_start, e); 37 | _xs = _xs.length < e ? new Array(e - _xs.length + 1).join("0") + _xs : _xs; 38 | zs = zs.substring(0, s_start); 39 | xs = _xs + xs; 40 | } 41 | zs = zs == "" ? "0" : zs; 42 | return (result[1] == "-" ? "-" : "") + zs + (xs ? "." + xs : ""); 43 | }; 44 | 45 | /** 46 | * 分析数字字符串 47 | * 48 | * @param {string} num NumberString 49 | * @returns object 50 | */ 51 | exports.getNumbResult = function (num) { 52 | var result = REG_NUMBER.exec(num.toString()); 53 | if (!result && REG_E.test(num.toString())) { 54 | result = REG_NUMBER.exec(e2ten(num.toString())); 55 | } 56 | if (result) { 57 | return { 58 | int: result[2], 59 | decimal: result[4], 60 | minus: result[1] == "-", 61 | num: result.slice(1, 3).join('') 62 | } 63 | } 64 | }; 65 | 66 | /** 67 | * 数组归一 (按索引覆盖合并数组,并清空被合并的数组) 68 | * 69 | * @param {array} baseArray 基础数组 70 | * @param {...array} array1 71 | * @returns array 72 | */ 73 | exports.centerArray = function centerArray(baseArray, array1 /*[, array2[, ...[, arrayN]]]*/) { 74 | baseArray.splice.apply(baseArray, [0, array1.length].concat(array1.splice(0, array1.length))); 75 | if (arguments.length > 2) { 76 | var r = [].slice.call(arguments, 2); 77 | r.unshift(baseArray); 78 | centerArray.apply(null, r); 79 | } 80 | return baseArray; 81 | }; 82 | 83 | /** 84 | * 检查对像属性 (非原型链) 85 | * 86 | * @param {object} obj 87 | * @param {string} key 88 | * @returns 89 | */ 90 | var hasAttr = exports.hasAttr = function (obj, key) { 91 | return Object.prototype.hasOwnProperty.call(obj, key); 92 | }; 93 | 94 | /** 95 | * 扩展对像(浅复制) 96 | * 97 | * @param {object} obj 98 | * @param {object} obj1 99 | * @returns 100 | */ 101 | exports.extend = function (obj) { 102 | var name 103 | , target = arguments[0] || {}; 104 | var objs = Array.prototype.slice.call(arguments, 1); 105 | 106 | for (var i = 0; i < objs.length; i++) { 107 | var _obj = objs[i]; 108 | for (name in _obj) { 109 | if (hasAttr(_obj, name)) { 110 | target[name] = _obj[name]; 111 | } 112 | } 113 | } 114 | return target; 115 | }; 116 | 117 | 118 | /** 119 | * 获取真实数位 120 | * 121 | * @param {number} index 中文单位的索引 122 | */ 123 | exports.getDigit = function (index) { 124 | return index >= 5 ? (index - 4) * 4 + 4 : index; 125 | }; 126 | 127 | /** 128 | * 往数组头部插入0 129 | * 130 | * @param {array} arr 131 | * @param {number} n 132 | */ 133 | exports.unshiftZero = function (arr, n) { 134 | if (n == null) n = 1; 135 | if (n <= 0) return; 136 | for (; n--;) arr.unshift(0); 137 | }; 138 | 139 | /** 140 | * 清理多余"零" 141 | * 142 | * @param {any} str 143 | * @param {any} zero "零"字符 144 | * @param {any} type 清理模式 ^ - 开头, $ - 结尾, nto1 - 多个连续变一个 145 | * @returns 146 | */ 147 | exports.clearZero = function (str, zero, type) { 148 | if (str == null) return ""; 149 | var reg0 = ~"*.?+$^[](){}|\\/".indexOf(zero) ? "\\" + zero : zero; 150 | var arg_s = new RegExp("^" + reg0 + "+") 151 | , arg_e = new RegExp(reg0 + "+$") 152 | , arg_d = new RegExp(reg0 + "{2}", "g"); 153 | str = str.toString(); 154 | if (type == "^") { 155 | str = str.replace(arg_s, ""); 156 | } 157 | if (!type || type == "$") { 158 | str = str.replace(arg_e, ""); 159 | } 160 | if (!type || type == "nto1") { 161 | str = str.replace(arg_d, zero); 162 | } 163 | return str; 164 | }; 165 | }); 166 | var utils_1 = utils.e2ten; 167 | var utils_2 = utils.getNumbResult; 168 | var utils_3 = utils.centerArray; 169 | var utils_4 = utils.hasAttr; 170 | var utils_5 = utils.extend; 171 | var utils_6 = utils.getDigit; 172 | var utils_7 = utils.unshiftZero; 173 | var utils_8 = utils.clearZero; 174 | 175 | /** 176 | * 阿拉伯数字转中文数字 177 | * 178 | * @param {String} num 阿拉伯数字/字符串 , 科学记数法字符串 179 | * @param {Object} opration 转换配置 180 | * { 181 | * ww: {万万化单位 | false} 182 | * tenMin: {十的口语化 | false} 183 | * } 184 | * @returns String 185 | */ 186 | function CL(num, options) { 187 | var result = utils.getNumbResult(num); 188 | if (!result) { 189 | return num; 190 | } 191 | options = options ? options : {}; 192 | var ch = this.ch //数字 193 | , ch_u = this.ch_u //单位 194 | , ch_f = this.ch_f || "" //负 195 | , ch_d = this.ch_d || "." //点 196 | , n0 = ch.charAt(0); //零 197 | var _int = result.int //整数部分 198 | , _decimal = result.decimal //小数部分 199 | , _minus = result.minus; //负数标识 200 | var int = "" 201 | , dicimal = "" 202 | , minus = _minus ? ch_f : ''; //符号位 203 | var encodeInt = function encodeInt(_int, _m, _dg) { 204 | _int = utils.getNumbResult(_int).int; 205 | var int = "" 206 | , tenm = arguments.length > 1 ? arguments[1] : options.tenMin 207 | , _length = _int.length; 208 | //一位整数 209 | if (_length == 1) return ch.charAt(+_int); 210 | if (_length <= 4) { //四位及以下 211 | for (var i = 0, n = _length; n--;) { 212 | var _num = +_int.charAt(i); 213 | int += (tenm && _length == 2 && i == 0 && _num == 1) ? "" : ch.charAt(_num); 214 | int += (_num && n ? ch_u.charAt(n) : ''); 215 | i++; 216 | } 217 | } else { //大数递归 218 | var d = _int.length / 4 >> 0 219 | , y = _int.length % 4; 220 | //"兆","京"等单位处理 221 | while (y == 0 || !ch_u.charAt(3 + d)) { 222 | y += 4; 223 | d--; 224 | } 225 | var _maxLeft = _int.substr(0, y), //最大单位前的数字 226 | _other = _int.substr(y); //剩余数字 227 | 228 | int = encodeInt(_maxLeft, tenm) + ch_u.charAt(3 + d) 229 | + (_other.charAt(0) == '0' ? n0 : '') //单位后有0则加零 230 | + encodeInt(_other, _other.length > 4 ? tenm : false); 231 | } 232 | int = utils.clearZero(int, n0); //修整零 233 | return int; 234 | }; 235 | 236 | //转换小数部分 237 | if (_decimal) { 238 | _decimal = utils.clearZero(_decimal, "0", "$"); //去除尾部0 239 | for (var x = 0; x < _decimal.length; x++) { 240 | dicimal += ch.charAt(+_decimal.charAt(x)); 241 | } 242 | dicimal = dicimal ? ch_d + dicimal : ""; 243 | } 244 | 245 | //转换整数部分 246 | int = encodeInt(_int); //转换整数 247 | 248 | //超级大数的万万化 249 | if (options.ww && ch_u.length > 5) { 250 | var dw_w = ch_u.charAt(4) 251 | , dw_y = ch_u.charAt(5); 252 | var lasty = int.lastIndexOf(dw_y); 253 | if (~lasty) { 254 | int = int.substring(0, lasty).replace(new RegExp(dw_y, 'g'), dw_w + dw_w) + int.substring(lasty); 255 | } 256 | } 257 | return minus + int + dicimal; 258 | } 259 | 260 | /** 261 | * 中文数字转阿拉伯数字 262 | * 263 | * @param {string} cnnumb 中文数字字符串 264 | * @returns Number 265 | */ 266 | function unCL(cnnumb) { 267 | cnnumb = cnnumb.toString(); 268 | var result = cnnumb.split(this.ch_d); 269 | var _int = result[0].replace(this.ch_f, "") 270 | , _decimal = result[1] 271 | , _minus = !!~result[0].indexOf(this.ch_f); 272 | 273 | var dw_s = this.ch_u.charAt(1) 274 | , dw_w = this.ch_u.charAt(4) 275 | , dw_y = this.ch_u.charAt(5); 276 | 277 | _int = _int.replace(new RegExp(dw_w + "{2}", "g"), dw_y); 278 | 279 | var cnarr = _int.split(''); 280 | var dw = 0, maxdw = 0; 281 | var rnum_a = [], num_a = [], _num_a = []; 282 | for (var i = 0; i < cnarr.length; i++) { 283 | var chr = cnarr[i]; 284 | var n = 0, u = 0; 285 | if (~(n = this.ch.indexOf(chr))) { 286 | //_num = _num*10 + n; 287 | if (n > 0) _num_a.unshift(n); 288 | //_num_a.unshift(n); 289 | } else if (~(u = this.ch_u.indexOf(chr))) { 290 | var digit = utils.getDigit(u); 291 | if (dw > u) {//正常情况 292 | utils.unshiftZero(_num_a, digit); 293 | utils.centerArray(num_a, _num_a); 294 | } else if (u >= maxdw) {//后跟大单位 295 | if (i == 0) _num_a = [1]; 296 | utils.centerArray(rnum_a, num_a, _num_a); 297 | if (rnum_a.length > 0) utils.unshiftZero(rnum_a, digit); 298 | maxdw = u; 299 | } else { 300 | if (_num_a.length == 0 && dw_s == chr) _num_a = [1]; 301 | utils.centerArray(num_a, _num_a); 302 | utils.unshiftZero(num_a, utils.getDigit(u)); 303 | dw = u; 304 | } 305 | } 306 | } 307 | utils.centerArray(rnum_a, num_a, _num_a).reverse(); 308 | if (rnum_a.length == 0) rnum_a.push(0); 309 | var decimal = 0; 310 | if (_decimal) { 311 | rnum_a.push('.'); 312 | decimal = '0.'; 313 | for (var i = 0; i < _decimal.length; i++) { 314 | decimal += this.ch.indexOf(_decimal.charAt(i)); 315 | rnum_a.push(this.ch.indexOf(_decimal.charAt(i))); 316 | } 317 | decimal = +decimal; 318 | 319 | } 320 | if (_minus) rnum_a.unshift('-'); 321 | return parseFloat(rnum_a.join('')); 322 | } 323 | 324 | /** 325 | * 阿拉伯数字转金额 326 | * 327 | * @param {String} num 阿拉伯数字/字符串 , 科学记数法字符串 328 | * @param {Object} options 转换配置 329 | * { 330 | * ww:{万万化开关 | true}, 331 | * unOmitYuan: {整数为0时不省略元| false}, 332 | * complete:{完整金额格式 | false}, 333 | * outSymbol:{是否输出金额符号 | true} 334 | * } 335 | * @returns String 336 | */ 337 | function toMoney(num, options) { 338 | var def = { ww: true, complete: false, outSymbol: true, unOmitYuan: false }; 339 | var result = utils.getNumbResult(num); 340 | var ch_0 = this.ch.charAt(0); 341 | options = typeof options == "object" ? options : {}; 342 | if (!result) { return num; } 343 | options = utils.extend(def, options); 344 | 345 | var _int = result.int 346 | , _decimal = result.decimal || ""; 347 | var t_str = options.outSymbol ? this.m_t : "" 348 | , zs_str = result.minus ? this.ch_f : "" 349 | , xs_str = ""; 350 | if (options.complete) { 351 | for (var i = 1; i < this.m_u.length; i++) { 352 | xs_str += CL.call(this, _decimal.charAt(i - 1) || "0") + this.m_u.charAt(i); 353 | } 354 | zs_str += CL.call(this, _int, options) + this.m_u.charAt(0); 355 | } else { 356 | var hasYuan = options.unOmitYuan || _int !== '0'; 357 | _decimal = _decimal.substr(0, this.m_u.length-1); 358 | _decimal = utils.clearZero(_decimal, "0", "$"); //去除尾部的0 359 | if (_decimal) { 360 | var mark_0; 361 | for (var i = 0; i < this.m_u.length - 1; i++) { 362 | if (_decimal.charAt(i) && _decimal.charAt(i) != "0") { 363 | xs_str += CL.call(this, _decimal.charAt(i)) + this.m_u.charAt(i + 1); 364 | mark_0 = false; 365 | } 366 | if (_decimal.charAt(i) === "0" && !mark_0) { 367 | if (i != 0 || _int !== "0") xs_str += ch_0; //当没有输出元时,小数前无需加零 368 | mark_0 = true; 369 | } 370 | } 371 | //if(_num == "0"){xs_str = utils.clearZero(xs_str,ch_0,"^")} 372 | } 373 | if (hasYuan || !xs_str) { 374 | zs_str += CL.call(this, _int, options) + this.m_u.charAt(0) + (result.decimal ? "" : this.m_z); 375 | } 376 | // if(result.minus) t_str += this.ch_f; 377 | } 378 | return t_str + zs_str + xs_str; 379 | } 380 | 381 | var src = { 382 | CL: CL, 383 | unCL: unCL, 384 | toMoney: toMoney 385 | }; 386 | 387 | function getNzhObjByLang(lang_s, lang_b) { 388 | return { 389 | encodeS: function (num, options) { 390 | options = utils.extend({ ww: true, tenMin: true }, options); 391 | return src.CL.call(lang_s, num, options); 392 | }, 393 | encodeB: function (num, options) { 394 | options = utils.extend({ ww: true }, options); 395 | return src.CL.call(lang_b, num, options); 396 | }, 397 | decodeS: function () { 398 | return src.unCL.apply(lang_s, arguments); 399 | }, 400 | decodeB: function () { 401 | return src.unCL.apply(lang_b, arguments); 402 | }, 403 | toMoney: function (num, options) { 404 | options = utils.extend({ ww: true }, options); 405 | return src.toMoney.call(lang_b, num, options); 406 | } 407 | } 408 | } 409 | var autoGet = getNzhObjByLang; 410 | 411 | var cn_s = { 412 | ch: '零一二三四五六七八九' 413 | ,ch_u: '个十百千万亿' 414 | ,ch_f: '负' 415 | ,ch_d: '点' 416 | }; 417 | 418 | var cn_b = { 419 | ch: '零壹贰叁肆伍陆柒捌玖' 420 | ,ch_u: '个拾佰仟万亿' 421 | ,ch_f: '负' 422 | ,ch_d: '点' 423 | ,m_t: '人民币' 424 | ,m_z: '整' 425 | ,m_u: '元角分' 426 | }; 427 | 428 | var hk_s = { 429 | ch: '零一二三四五六七八九' 430 | ,ch_u: '個十百千萬億' 431 | ,ch_f: '負' 432 | ,ch_d: '點' 433 | }; 434 | 435 | var hk_b = { 436 | ch: '零壹貳參肆伍陸柒捌玖' 437 | ,ch_u: '個拾佰仟萬億' 438 | ,ch_f: '負' 439 | ,ch_d: '點' 440 | ,m_t: '$' 441 | ,m_z: '整' 442 | ,m_u: '圓角分' 443 | }; 444 | 445 | var langs = { 446 | s:cn_s, 447 | b:cn_b, 448 | hk_s:hk_s, 449 | hk_b:hk_b 450 | }; 451 | var Nzh = function(lang){ 452 | this.lang = lang; 453 | this.encode = function(){return src.CL.apply(lang,arguments)}; 454 | this.decode = function(){return src.unCL.apply(lang,arguments)}; 455 | this.toMoney = function(){return src.toMoney.apply(lang,arguments)}; 456 | }; 457 | Nzh.langs = langs; 458 | Nzh.cn = autoGet(langs.s,langs.b); 459 | Nzh.hk = autoGet(langs.hk_s,langs.hk_b); 460 | var nzh = Nzh; 461 | 462 | export default nzh; 463 | -------------------------------------------------------------------------------- /nzh.d.ts: -------------------------------------------------------------------------------- 1 | interface Options { 2 | /* 3 | * 十的口语化开关, 默认值为 false 4 | * 注: Nzh.cn和Nzh.hk中的encodeS方法默认 true 5 | * */ 6 | tenMin?: boolean; 7 | /** 8 | * "万万"化开关, 默认值为 true 9 | * */ 10 | ww?: boolean; 11 | } 12 | interface ToMoneyOptions extends Options { 13 | /** 14 | * 输出完整金额开关, toMoney 函数专用配置, 默认 false 15 | * */ 16 | complete?: boolean; 17 | /* 18 | * 输出金额前缀字符, toMoney 函数专用配置, 默认 true 19 | * */ 20 | outSymbol?: boolean; 21 | /* 22 | * 个位为0时不省略元,toMoney 函数专用配置, 默认 false 23 | * */ 24 | unOmitYuan?: boolean; 25 | /** 26 | * 不以源数据加整,以输出结果加“整”(只要输出的结果没有到分位就加“整”) 27 | */ 28 | forceZheng?: boolean; 29 | } 30 | interface Lang { 31 | ch: string; 32 | ch_u: string; 33 | ch_f: string; 34 | ch_d: string; 35 | m_t: string; 36 | m_z: string; 37 | m_u: string; 38 | } 39 | interface Langs { 40 | s: Lang; 41 | b: Lang; 42 | hk_s: Lang; 43 | hk_b: Lang; 44 | } 45 | interface BuiltIn { 46 | encodeS(num: number | string, options?: Options): string; 47 | encodeB(num: number | string, options?: Options): string; 48 | decodeS(zhnum: string, options?: Options): string; 49 | decodeB(zhnum: string, options?: Options): string; 50 | toMoney(num: number | string, options?: ToMoneyOptions): string; 51 | } 52 | 53 | declare module 'nzh' { 54 | export default class Nzh { 55 | constructor(lang: Lang); 56 | public encode(num: number | string, options?: Options): string; 57 | public decode(zhnum: string, options?: Options): string; 58 | public toMoney(num: number | string, options?: ToMoneyOptions): string; 59 | 60 | static cn: BuiltIn; 61 | static hk: BuiltIn; 62 | static langs: Langs; 63 | } 64 | } 65 | 66 | declare module 'nzh/cn' { 67 | const nzhcn:BuiltIn; 68 | export default nzhcn; 69 | } 70 | 71 | declare module 'nzh/hk' { 72 | const nzhhk:BuiltIn; 73 | export default nzhhk; 74 | } 75 | -------------------------------------------------------------------------------- /nzh.js: -------------------------------------------------------------------------------- 1 | var nzhClass = require("./src/"); 2 | var utils = require("./src/utils") 3 | var getNzhObjByLang = require("./src/autoGet"); 4 | var langs = { 5 | s:require("./src/langs/cn_s"), 6 | b:require("./src/langs/cn_b"), 7 | hk_s:require("./src/langs/hk_s"), 8 | hk_b:require("./src/langs/hk_b") 9 | } 10 | var Nzh = function(lang){ 11 | this.lang = lang; 12 | this.encode = function(){return nzhClass.CL.apply(lang,arguments)} 13 | this.decode = function(){return nzhClass.unCL.apply(lang,arguments)} 14 | this.toMoney = function(){return nzhClass.toMoney.apply(lang,arguments)} 15 | } 16 | Nzh.langs = langs; 17 | Nzh.cn = getNzhObjByLang(langs.s,langs.b); 18 | Nzh.hk = getNzhObjByLang(langs.hk_s,langs.hk_b); 19 | module.exports = Nzh; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nzh", 3 | "version": "1.0.14", 4 | "description": "数字转中文,大写,金额", 5 | "homepage": "http://cnwhy.github.io/nzh", 6 | "main": "nzh.js", 7 | "types": "nzh.d.ts", 8 | "exports": { 9 | ".": { 10 | "types": "./nzh.d.ts", 11 | "import": "./nzh.js", 12 | "require": "./nzh.js" 13 | }, 14 | "./cn": { 15 | "types": "./nzh.d.ts", 16 | "import": "./cn.js", 17 | "require": "./cn.js" 18 | }, 19 | "./hk": { 20 | "types": "./nzh.d.ts", 21 | "import": "./hk.js", 22 | "require": "./hk.js" 23 | } 24 | }, 25 | "files": [ 26 | "src/*", 27 | "dist/*", 28 | "nzh.js", 29 | "cn.js", 30 | "hk.js", 31 | "nzh.d.ts" 32 | ], 33 | "scripts": { 34 | "test": "./node_modules/.bin/_mocha test/test_mocha.js", 35 | "build": "gulp build" 36 | }, 37 | "repository": { 38 | "type": "git", 39 | "url": "https://github.com/cnwhy/nzh.git" 40 | }, 41 | "keywords": [ 42 | "数字转中文", 43 | "数字转金额", 44 | "中文数字转阿拉伯数字", 45 | "中文数字" 46 | ], 47 | "author": { 48 | "name": "cnwhy", 49 | "email": "w.why@163.com" 50 | }, 51 | "devDependencies": { 52 | "gulp": "^3.9.1", 53 | "gulp-browserify": "^0.5.1", 54 | "gulp-header": "^1.8.8", 55 | "gulp-mocha": "^3.0.1", 56 | "gulp-mocha-phantomjs": "^0.12.1", 57 | "gulp-rename": "^1.2.2", 58 | "gulp-uglify": "^2.0.1", 59 | "rollup": "^0.63.4", 60 | "rollup-plugin-commonjs": "^9.1.3", 61 | "rollup-plugin-node-resolve": "^3.3.0" 62 | }, 63 | "license": "BSD-2-Clause" 64 | } 65 | -------------------------------------------------------------------------------- /src/autoGet.js: -------------------------------------------------------------------------------- 1 | var nzhClass = require("./"); 2 | var utils = require("./utils") 3 | function getNzhObjByLang(lang_s, lang_b) { 4 | return { 5 | encodeS: function (num, options) { 6 | options = utils.extend({ ww: true, tenMin: true }, options); 7 | return nzhClass.CL.call(lang_s, num, options); 8 | }, 9 | encodeB: function (num, options) { 10 | options = utils.extend({ ww: true }, options); 11 | return nzhClass.CL.call(lang_b, num, options); 12 | }, 13 | decodeS: function () { 14 | return nzhClass.unCL.apply(lang_s, arguments); 15 | }, 16 | decodeB: function () { 17 | return nzhClass.unCL.apply(lang_b, arguments); 18 | }, 19 | toMoney: function (num, options) { 20 | options = utils.extend({ ww: true }, options); 21 | return nzhClass.toMoney.call(lang_b, num, options); 22 | } 23 | } 24 | } 25 | module.exports = getNzhObjByLang; -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | var utils = require("./utils"); 2 | 3 | /** 4 | * 阿拉伯数字转中文数字 5 | * 6 | * @param {String} num 阿拉伯数字/字符串 , 科学记数法字符串 7 | * @param {Object} opration 转换配置 8 | * { 9 | * ww: {万万化单位 | false} 10 | * tenMin: {十的口语化 | false} 11 | * } 12 | * @returns String 13 | */ 14 | function CL(num, options) { 15 | var result = utils.getNumbResult(num) 16 | if (!result) { 17 | return num; 18 | } 19 | options = options ? options : {}; 20 | var ch = this.ch //数字 21 | , ch_u = this.ch_u //单位 22 | , ch_f = this.ch_f || "" //负 23 | , ch_d = this.ch_d || "." //点 24 | , n0 = ch.charAt(0); //零 25 | var _int = result.int //整数部分 26 | , _decimal = result.decimal //小数部分 27 | , _minus = result.minus; //负数标识 28 | var int = "" 29 | , dicimal = "" 30 | , minus = _minus ? ch_f : ''; //符号位 31 | var encodeInt = function encodeInt(_int, _m, _dg) { 32 | _int = utils.getNumbResult(_int).int; 33 | var int = "" 34 | , tenm = arguments.length > 1 ? arguments[1] : options.tenMin 35 | , _length = _int.length; 36 | //一位整数 37 | if (_length == 1) return ch.charAt(+_int); 38 | if (_length <= 4) { //四位及以下 39 | for (var i = 0, n = _length; n--;) { 40 | var _num = +_int.charAt(i); 41 | int += (tenm && _length == 2 && i == 0 && _num == 1) ? "" : ch.charAt(_num); 42 | int += (_num && n ? ch_u.charAt(n) : '') 43 | i++; 44 | } 45 | } else { //大数递归 46 | var d = _int.length / 4 >> 0 47 | , y = _int.length % 4; 48 | //"兆","京"等单位处理 49 | while (y == 0 || !ch_u.charAt(3 + d)) { 50 | y += 4; 51 | d--; 52 | } 53 | var _maxLeft = _int.substr(0, y), //最大单位前的数字 54 | _other = _int.substr(y); //剩余数字 55 | 56 | int = encodeInt(_maxLeft, tenm) + ch_u.charAt(3 + d) 57 | + (_other.charAt(0) == '0' ? n0 : '') //单位后有0则加零 58 | + encodeInt(_other, _other.length > 4 ? tenm : false) 59 | } 60 | int = utils.clearZero(int, n0); //修整零 61 | return int; 62 | } 63 | 64 | //转换小数部分 65 | if (_decimal) { 66 | _decimal = utils.clearZero(_decimal, "0", "$"); //去除尾部0 67 | for (var x = 0; x < _decimal.length; x++) { 68 | dicimal += ch.charAt(+_decimal.charAt(x)); 69 | } 70 | dicimal = dicimal ? ch_d + dicimal : ""; 71 | } 72 | 73 | //转换整数部分 74 | int = encodeInt(_int); //转换整数 75 | 76 | //超级大数的万万化 77 | if (options.ww && ch_u.length > 5) { 78 | var dw_w = ch_u.charAt(4) 79 | , dw_y = ch_u.charAt(5); 80 | var lasty = int.lastIndexOf(dw_y); 81 | if (~lasty) { 82 | int = int.substring(0, lasty).replace(new RegExp(dw_y, 'g'), dw_w + dw_w) + int.substring(lasty); 83 | } 84 | } 85 | return minus + int + dicimal; 86 | } 87 | 88 | /** 89 | * 中文数字转阿拉伯数字 90 | * 91 | * @param {string} cnnumb 中文数字字符串 92 | * @returns Number 93 | */ 94 | function unCL(cnnumb, options) { 95 | cnnumb = cnnumb.toString(); 96 | var result = cnnumb.split(this.ch_d); 97 | var _int = result[0].replace(this.ch_f, "") 98 | , _decimal = result[1] 99 | , _minus = !!~result[0].indexOf(this.ch_f); 100 | 101 | var dw_s = this.ch_u.charAt(1) 102 | , dw_w = this.ch_u.charAt(4) 103 | , dw_y = this.ch_u.charAt(5); 104 | 105 | _int = _int.replace(new RegExp(dw_w + "{2}(?!"+dw_w+")", "g"), dw_y); 106 | var cnarr = _int.split(''); 107 | var dw = 0, maxdw = 0; 108 | var rnum_a = [], num_a = [], _num_a = []; 109 | for (var i = 0; i < cnarr.length; i++) { 110 | var chr = cnarr[i]; 111 | var n = 0, u = 0; 112 | if (~(n = this.ch.indexOf(chr))) { 113 | //_num = _num*10 + n; 114 | if (n > 0) _num_a.unshift(n); 115 | //_num_a.unshift(n); 116 | } else if (~(u = this.ch_u.indexOf(chr))) { 117 | var digit = utils.getDigit(u); 118 | if (dw > u) {//正常情况 119 | utils.unshiftZero(_num_a, digit); 120 | utils.centerArray(num_a, _num_a); 121 | } else if (u >= maxdw) {//后跟大单位 122 | if (i == 0) _num_a = [1]; 123 | utils.centerArray(rnum_a, num_a, _num_a); 124 | if (rnum_a.length > 0) utils.unshiftZero(rnum_a, digit); 125 | maxdw = u; 126 | } else { 127 | if (_num_a.length == 0 && dw_s == chr) _num_a = [1]; 128 | utils.centerArray(num_a, _num_a); 129 | utils.unshiftZero(num_a, utils.getDigit(u)); 130 | dw = u; 131 | } 132 | } 133 | } 134 | utils.centerArray(rnum_a, num_a, _num_a).reverse(); 135 | if (rnum_a.length == 0) rnum_a.push(0); 136 | var decimal = 0; 137 | if (_decimal) { 138 | rnum_a.push('.') 139 | decimal = '0.' 140 | for (var i = 0; i < _decimal.length; i++) { 141 | decimal += this.ch.indexOf(_decimal.charAt(i)); 142 | rnum_a.push(this.ch.indexOf(_decimal.charAt(i))); 143 | } 144 | decimal = +decimal; 145 | 146 | } 147 | if (_minus) rnum_a.unshift('-'); 148 | return (options && options.outputString) ? rnum_a.join('') : parseFloat(rnum_a.join('')); 149 | } 150 | 151 | /** 152 | * 阿拉伯数字转金额 153 | * 154 | * @param {String} num 阿拉伯数字/字符串 , 科学记数法字符串 155 | * @param {Object} options 转换配置 156 | * { 157 | * ww:{万万化开关 | true}, 158 | * unOmitYuan: {整数为0时不省略元| false}, 159 | * complete:{完整金额格式 | false}, 160 | * outSymbol:{是否输出金额符号 | true} 161 | * forceZheng:{以转换结果加“整” | false} 162 | * } 163 | * @returns String 164 | */ 165 | function toMoney(num, options) { 166 | var def = { ww: true, complete: false, outSymbol: true, unOmitYuan: false, forceZheng: false }; 167 | var result = utils.getNumbResult(num); 168 | var ch_0 = this.ch.charAt(0); 169 | options = typeof options == "object" ? options : {}; 170 | if (!result) { return num; } 171 | options = utils.extend(def, options); 172 | 173 | var _int = result.int 174 | , _decimal = result.decimal || ""; 175 | var t_str = options.outSymbol ? this.m_t : "" 176 | , zs_str = result.minus ? this.ch_f : "" 177 | , xs_str = ""; 178 | if (options.complete) { 179 | for (var i = 1; i < this.m_u.length; i++) { 180 | xs_str += CL.call(this, _decimal.charAt(i - 1) || "0") + this.m_u.charAt(i); 181 | } 182 | zs_str += CL.call(this, _int, options) + this.m_u.charAt(0); 183 | } else { 184 | var hasYuan = options.unOmitYuan || _int !== '0'; 185 | _decimal = _decimal.substr(0, this.m_u.length-1); 186 | _decimal = utils.clearZero(_decimal, "0", "$"); //去除尾部的0 187 | if (_decimal) { 188 | var mark_0; 189 | for (var i = 0; i < this.m_u.length - 1; i++) { 190 | if (_decimal.charAt(i) && _decimal.charAt(i) != "0") { 191 | xs_str += CL.call(this, _decimal.charAt(i)) + this.m_u.charAt(i + 1); 192 | mark_0 = false; 193 | } 194 | if (_decimal.charAt(i) === "0" && !mark_0) { 195 | if (i != 0 || _int !== "0") xs_str += ch_0; //当没有输出元时,小数前无需加零 196 | mark_0 = true; 197 | } 198 | } 199 | //if(_num == "0"){xs_str = utils.clearZero(xs_str,ch_0,"^")} 200 | } 201 | if (hasYuan || !xs_str) { 202 | zs_str += CL.call(this, _int, options) + this.m_u.charAt(0); 203 | } 204 | if(!options.forceZheng) { 205 | zs_str += result.decimal ? "" : this.m_z 206 | }else if(xs_str == '' || xs_str.charAt(xs_str.length-1) !== this.m_u[2]){ 207 | xs_str += this.m_z 208 | } 209 | // if(result.minus) t_str += this.ch_f; 210 | if(options.forceZheng){ 211 | } 212 | } 213 | return t_str + zs_str + xs_str; 214 | } 215 | 216 | module.exports = { 217 | CL: CL, 218 | unCL: unCL, 219 | toMoney: toMoney 220 | } -------------------------------------------------------------------------------- /src/langs/cn_b.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ch: '零壹贰叁肆伍陆柒捌玖' 3 | ,ch_u: '个拾佰仟万亿' 4 | ,ch_f: '负' 5 | ,ch_d: '点' 6 | ,m_t: '人民币' 7 | ,m_z: '整' 8 | ,m_u: '元角分' 9 | } -------------------------------------------------------------------------------- /src/langs/cn_s.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ch: '零一二三四五六七八九' 3 | ,ch_u: '个十百千万亿' 4 | ,ch_f: '负' 5 | ,ch_d: '点' 6 | } -------------------------------------------------------------------------------- /src/langs/hk_b.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ch: '零壹貳參肆伍陸柒捌玖' 3 | ,ch_u: '個拾佰仟萬億' 4 | ,ch_f: '負' 5 | ,ch_d: '點' 6 | ,m_t: '$' 7 | ,m_z: '整' 8 | ,m_u: '圓角分' 9 | } -------------------------------------------------------------------------------- /src/langs/hk_s.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ch: '零一二三四五六七八九' 3 | ,ch_u: '個十百千萬億' 4 | ,ch_f: '負' 5 | ,ch_d: '點' 6 | } -------------------------------------------------------------------------------- /src/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var REG_NUMBER = /^([+-])?0*(\d+)(\.(\d+))?$/; 3 | var REG_E = /^([+-])?0*(\d+)(\.(\d+))?e(([+-])?(\d+))$/i; 4 | 5 | /** 6 | * 科学计数法转十进制 7 | * 8 | * @param {string} num 科学记数法字符串 9 | * @returns string 10 | */ 11 | var e2ten = exports.e2ten = function (num) { 12 | var result = REG_E.exec(num.toString()); 13 | if (!result) return num; 14 | var zs = result[2] 15 | , xs = result[4] || "" 16 | , e = result[5] ? +result[5] : 0; 17 | if (e > 0) { 18 | var _zs = xs.substr(0, e); 19 | _zs = _zs.length < e ? _zs + new Array(e - _zs.length + 1).join("0") : _zs; 20 | xs = xs.substr(e); 21 | zs += _zs; 22 | } else { 23 | e = -e; 24 | var s_start = zs.length - e; 25 | s_start = s_start < 0 ? 0 : s_start; 26 | var _xs = zs.substr(s_start, e); 27 | _xs = _xs.length < e ? new Array(e - _xs.length + 1).join("0") + _xs : _xs; 28 | zs = zs.substring(0, s_start); 29 | xs = _xs + xs; 30 | } 31 | zs = zs == "" ? "0" : zs; 32 | return (result[1] == "-" ? "-" : "") + zs + (xs ? "." + xs : ""); 33 | } 34 | 35 | /** 36 | * 分析数字字符串 37 | * 38 | * @param {string} num NumberString 39 | * @returns object 40 | */ 41 | exports.getNumbResult = function (num) { 42 | var result = REG_NUMBER.exec(num.toString()); 43 | if (!result && REG_E.test(num.toString())) { 44 | result = REG_NUMBER.exec(e2ten(num.toString())) 45 | } 46 | if (result) { 47 | return { 48 | int: result[2], 49 | decimal: result[4], 50 | minus: result[1] == "-", 51 | num: result.slice(1, 3).join('') 52 | } 53 | } 54 | } 55 | 56 | /** 57 | * 数组归一 (按索引覆盖合并数组,并清空被合并的数组) 58 | * 59 | * @param {array} baseArray 基础数组 60 | * @param {...array} array1 61 | * @returns array 62 | */ 63 | exports.centerArray = function centerArray(baseArray, array1 /*[, array2[, ...[, arrayN]]]*/) { 64 | baseArray.splice.apply(baseArray, [0, array1.length].concat(array1.splice(0, array1.length))); 65 | if (arguments.length > 2) { 66 | var r = [].slice.call(arguments, 2); 67 | r.unshift(baseArray); 68 | centerArray.apply(null, r); 69 | } 70 | return baseArray; 71 | } 72 | 73 | /** 74 | * 检查对像属性 (非原型链) 75 | * 76 | * @param {object} obj 77 | * @param {string} key 78 | * @returns 79 | */ 80 | var hasAttr = exports.hasAttr = function (obj, key) { 81 | return Object.prototype.hasOwnProperty.call(obj, key); 82 | } 83 | 84 | /** 85 | * 扩展对像(浅复制) 86 | * 87 | * @param {object} obj 88 | * @param {object} obj1 89 | * @returns 90 | */ 91 | exports.extend = function (obj) { 92 | var name 93 | , target = arguments[0] || {}; 94 | var objs = Array.prototype.slice.call(arguments, 1); 95 | 96 | for (var i = 0; i < objs.length; i++) { 97 | var _obj = objs[i]; 98 | for (name in _obj) { 99 | if (hasAttr(_obj, name)) { 100 | target[name] = _obj[name]; 101 | } 102 | } 103 | } 104 | return target; 105 | } 106 | 107 | 108 | /** 109 | * 获取真实数位 110 | * 111 | * @param {number} index 中文单位的索引 112 | */ 113 | exports.getDigit = function (index) { 114 | return index >= 5 ? (index - 4) * 4 + 4 : index; 115 | } 116 | 117 | /** 118 | * 往数组头部插入0 119 | * 120 | * @param {array} arr 121 | * @param {number} n 122 | */ 123 | exports.unshiftZero = function (arr, n) { 124 | if (n == null) n = 1; 125 | if (n <= 0) return; 126 | for (; n--;) arr.unshift(0); 127 | } 128 | 129 | /** 130 | * 清理多余"零" 131 | * 132 | * @param {any} str 133 | * @param {any} zero "零"字符 134 | * @param {any} type 清理模式 ^ - 开头, $ - 结尾, nto1 - 多个连续变一个 135 | * @returns 136 | */ 137 | exports.clearZero = function (str, zero, type) { 138 | if (str == null) return ""; 139 | var reg0 = ~"*.?+$^[](){}|\\/".indexOf(zero) ? "\\" + zero : zero; 140 | var arg_s = new RegExp("^" + reg0 + "+") 141 | , arg_e = new RegExp(reg0 + "+$") 142 | , arg_d = new RegExp(reg0 + "{2}", "g") 143 | str = str.toString(); 144 | if (type == "^") { 145 | str = str.replace(arg_s, ""); 146 | } 147 | if (!type || type == "$") { 148 | str = str.replace(arg_e, ""); 149 | } 150 | if (!type || type == "nto1") { 151 | str = str.replace(arg_d, zero); 152 | } 153 | return str; 154 | } -------------------------------------------------------------------------------- /test/browser/amd.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test AMD 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 66 | 69 | 70 | -------------------------------------------------------------------------------- /test/browser/cmd.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test CMD 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 66 | 69 | 70 | -------------------------------------------------------------------------------- /test/browser/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test script 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 24 | 27 | 28 | -------------------------------------------------------------------------------- /test/browser/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | test 5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/temp.js: -------------------------------------------------------------------------------- 1 | const nzhcn = require('../cn'); 2 | 3 | console.log(nzhcn.decodeS('一万万万万亿', {outputString: false})); // 1e+24 4 | console.log(nzhcn.decodeS('一万万万万亿', {outputString: true})); // "1000000000000000000000000" 5 | console.log(nzhcn.toMoney("0.0")); -------------------------------------------------------------------------------- /test/testData.js: -------------------------------------------------------------------------------- 1 | (function (name, factory) { 2 | if (typeof process === "object" && typeof module === "object" && typeof module.exports) { 3 | module.exports = factory(); 4 | } else if (typeof define === 'function' && (define.amd || define.cmd)) { 5 | define([], factory); 6 | } else if (typeof window !== "undefined" || typeof self !== "undefined") { 7 | var global = typeof window !== "undefined" ? window : self; 8 | global[name] = factory(); 9 | } else { 10 | throw new Error("加载 " + name + " 模块失败!,请检查您的环境!") 11 | } 12 | }('testData', function () { 13 | var testData = {}; 14 | testData.toCN = { 15 | name: "数字,中文互转", 16 | its: [ 17 | { 18 | name: "整数", 19 | data: [ 20 | ["1", "一"], 21 | ["-1", "负一"], 22 | ["001", "一"], 23 | ["010", "一十"], 24 | ["0010", "一十"], 25 | ["12", "一十二"], 26 | ["123", "一百二十三"], 27 | ["1234", "一千二百三十四"], 28 | ["12345", "一万二千三百四十五"], 29 | ["123456", "一十二万三千四百五十六"], 30 | ["1234567", "一百二十三万四千五百六十七"], 31 | ["12345678", "一千二百三十四万五千六百七十八"], 32 | ["123456789", "一亿二千三百四十五万六千七百八十九"], 33 | ["1234567890", "一十二亿三千四百五十六万七千八百九十"], 34 | ["12301230123", "一百二十三亿零一百二十三万零一百二十三"], 35 | ["123012301230", "一千二百三十亿一千二百三十万一千二百三十"], 36 | ["1230123012301", "一万二千三百零一亿二千三百零一万二千三百零一"], 37 | ["12301230123012", "一十二万三千零一十二亿三千零一十二万三千零一十二"], 38 | ["10000000000000000", "一亿亿"], 39 | ["100000001100000000", "一十亿零一十一亿"], 40 | ] 41 | }, 42 | { 43 | name: "插零测试", 44 | data:[ 45 | ["0", "零"], 46 | ["00", "零"], 47 | ["000", "零"], 48 | ["101", "一百零一"], 49 | ["1001", "一千零一"], 50 | ["10001", "一万零一"], 51 | ["100001", "一十万零一"], 52 | ["100010", "一十万零一十"], 53 | ["100100","一十万零一百"], 54 | ["101000","一十万一千"], 55 | ["1010001000","一十亿一千万一千"], 56 | ["1000001000","一十亿零一千"], 57 | ] 58 | }, 59 | { 60 | name: "有小数", 61 | data: [ 62 | ["0.0", "零"], 63 | ["1.0", "一"], 64 | ["1.00", "一"], 65 | ["0.1", "零点一"], 66 | ["-0.1", "负零点一"], 67 | ["00.1", "零点一"], 68 | ["01.1", "一点一"], 69 | ["1.10", "一点一"], 70 | ["10.01", "一十点零一"], 71 | ["100111.11", "一十万零一百一十一点一一"], 72 | ["1e16", "一亿亿"] 73 | ] 74 | }, 75 | { 76 | name: "科学记数法", 77 | data: [ 78 | ["100e-3", "零点一"], 79 | ["1.01e+3", "一千零一十"], 80 | ["1.01e3", "一千零一十"], 81 | ["1.01E3", "一千零一十"] 82 | ] 83 | }, 84 | { 85 | name: "十的口语化测试", 86 | args: { tenMin: true }, 87 | data: [ 88 | ["10", "十"], 89 | ["15", "十五"], 90 | ["100000", "十万"], 91 | ["100010", "十万零一十"], 92 | ["1000100000", "十亿零十万"] 93 | ] 94 | }, 95 | { 96 | name: "单位万万化", 97 | args: { ww: true }, 98 | data: [ 99 | ["1e16", "一万万亿"], 100 | ["10.011e16", "一十万万零一百一十万亿"] 101 | ] 102 | }, 103 | { 104 | name: "输出字符串开关", 105 | args: { outputString: true }, 106 | data: [ 107 | ["100000000000000000000", "一万亿亿"], 108 | ["-10000000000000000000000000000", "负一万亿亿亿"], 109 | ] 110 | }, 111 | { 112 | name: "输出字符串开关1", 113 | args: { outputString: true, ww: true }, 114 | data: [ 115 | ["100000000000000000000", "一万万万亿"], 116 | ["-10000000000000000000000000000", "负一万万万万万亿"], 117 | ] 118 | } 119 | ] 120 | } 121 | 122 | testData.toMoney = { 123 | name: "数字转人民币金额", 124 | its: [ 125 | { 126 | name: "整数", 127 | data: [ 128 | ["0", "人民币零元整"], 129 | ["00", "人民币零元整"], 130 | ["000", "人民币零元整"], 131 | ["1", "人民币壹元整"], 132 | ["-1", "人民币负壹元整"], 133 | ["001", "人民币壹元整"], 134 | ["-001", "人民币负壹元整"], 135 | ["010", "人民币壹拾元整"], 136 | ["0010", "人民币壹拾元整"], 137 | ["12", "人民币壹拾贰元整",], 138 | ["3456789", "人民币叁佰肆拾伍万陆仟柒佰捌拾玖元整"], 139 | ["1001000021", "人民币壹拾亿零壹佰万零贰拾壹元整"], 140 | ["10000000000000000", "人民币壹万万亿元整"], 141 | ["100000001100000000", "人民币壹拾万万零壹拾壹亿元整"] 142 | ] 143 | }, 144 | { 145 | name: "有小数", 146 | data: [ 147 | ["0.0", "人民币零元"], 148 | ["0.001", "人民币零元"], 149 | ["-0.001", "人民币负零元"], 150 | ["1.0", "人民币壹元"], 151 | ["-1.0", "人民币负壹元"], 152 | ["1.00", "人民币壹元"], 153 | ["0.1", "人民币壹角"], 154 | ["-0.1", "人民币负壹角"], 155 | ["00.1", "人民币壹角"], 156 | ["0.01", "人民币壹分"], 157 | ["01.1", "人民币壹元壹角"], 158 | ["1.10", "人民币壹元壹角"], 159 | ["1.101", "人民币壹元壹角"], 160 | ["10.01", "人民币壹拾元零壹分"], 161 | ["10.012", "人民币壹拾元零壹分"], 162 | ["100111.11", "人民币壹拾万零壹佰壹拾壹元壹角壹分"] 163 | ] 164 | }, 165 | { 166 | name: "科学记数法", 167 | data: [ 168 | ["100e-3", "人民币壹角"], 169 | ["1.01e+3", "人民币壹仟零壹拾元整"], 170 | ["1.01e3", "人民币壹仟零壹拾元整"], 171 | ["1.01E3", "人民币壹仟零壹拾元整"] 172 | ] 173 | }, 174 | { 175 | name: "不输出前辍", 176 | args: { outSymbol: false }, 177 | data: [ 178 | ["1", "壹元整"] 179 | ] 180 | }, 181 | { 182 | name: "不省略元", 183 | args: { unOmitYuan: true }, 184 | data: [ 185 | ["0.1", "人民币零元壹角"], 186 | ["-0.1", "人民币负零元壹角"], 187 | ["0.01", "人民币零元壹分"], 188 | ["00.01", "人民币零元壹分"], 189 | // ["0.01", "人民币零元零壹分"] 190 | ["-0.01", "人民币负零元壹分"], 191 | ["0.012", "人民币零元壹分"], 192 | ] 193 | }, 194 | { 195 | name: "完整格式测试", 196 | args: { complete: true }, 197 | data: [ 198 | ["10", "人民币壹拾元零角零分"], 199 | ["0", "人民币零元零角零分"], 200 | ["0.1", "人民币零元壹角零分"], 201 | ["0.01", "人民币零元零角壹分"] 202 | ] 203 | }, 204 | { 205 | name: "不输出前辍", 206 | args: { outSymbol: false }, 207 | data: [ 208 | ["1", "壹元整"] 209 | ] 210 | }, 211 | { 212 | name: "强制输出'整'", 213 | args: { forceZheng: true }, 214 | data: [ 215 | ["1.00", "人民币壹元整"], 216 | ["1.1", "人民币壹元壹角整"], 217 | ["0.001", "人民币零元整"], 218 | ["1.001", "人民币壹元整"], 219 | ["0.10", "人民币壹角整"] 220 | ] 221 | } 222 | ] 223 | } 224 | 225 | testData.custom = { 226 | name: "自定义测试", 227 | lang: { 228 | ch: "零壹贰叁肆伍陆柒捌玖" 229 | , ch_u: "个拾佰仟万亿兆京" 230 | , ch_f: "负" 231 | , ch_d: "点" 232 | , m_t: "¥" 233 | , m_z: "正" 234 | , m_u: "元角分厘" 235 | }, 236 | testCL: 237 | { 238 | name: "中文,数字互转", 239 | data: [ 240 | ["1000000000000", "壹兆"], 241 | ["10000000000000000", "壹京"] 242 | ] 243 | }, 244 | testMoney: 245 | { 246 | name: "转金额", 247 | data: [ 248 | ["1", "¥壹元正"], 249 | ["1.234", "¥壹元贰角叁分肆厘"] 250 | ], 251 | its: [ 252 | { 253 | name: "完整格式测试", 254 | args: { complete: true }, 255 | data: [ 256 | ["10", "¥壹拾元零角零分零厘"], 257 | ["0", "¥零元零角零分零厘"], 258 | ["0.1", "¥零元壹角零分零厘"], 259 | ["0.011", "¥零元零角壹分壹厘"] 260 | ] 261 | } 262 | ] 263 | } 264 | } 265 | return testData; 266 | })) -------------------------------------------------------------------------------- /test/test_mocha.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var assert = require("assert"); 3 | var Nzh = require("../"); 4 | var testData = require("./testData"); 5 | var toCN = testData.toCN; 6 | var toMoney = testData.toMoney; 7 | var custom = testData.custom; 8 | 9 | function inTest(td,fn){ 10 | describe(td.name,function(){ 11 | if(td.its){ 12 | for(var i=0; i