nzh.cn.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. /*!
  2. * nzh v1.0.10
  3. * Homepage http://cnwhy.github.io/nzh
  4. * License BSD-2-Clause
  5. */
  6. (function (global, factory) {
  7. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  8. typeof define === 'function' && define.amd ? define(factory) :
  9. (global.Nzh = factory());
  10. }(this, (function () { 'use strict';
  11. function createCommonjsModule(fn, module) {
  12. return module = { exports: {} }, fn(module, module.exports), module.exports;
  13. }
  14. var utils = createCommonjsModule(function (module, exports) {
  15. var REG_NUMBER = /^([+-])?0*(\d+)(\.(\d+))?$/;
  16. var REG_E = /^([+-])?0*(\d+)(\.(\d+))?e(([+-])?(\d+))$/i;
  17. /**
  18. * 科学计数法转十进制
  19. *
  20. * @param {string} num 科学记数法字符串
  21. * @returns string
  22. */
  23. var e2ten = exports.e2ten = function (num) {
  24. var result = REG_E.exec(num.toString());
  25. if (!result) return num;
  26. var zs = result[2]
  27. , xs = result[4] || ""
  28. , e = result[5] ? +result[5] : 0;
  29. if (e > 0) {
  30. var _zs = xs.substr(0, e);
  31. _zs = _zs.length < e ? _zs + new Array(e - _zs.length + 1).join("0") : _zs;
  32. xs = xs.substr(e);
  33. zs += _zs;
  34. } else {
  35. e = -e;
  36. var s_start = zs.length - e;
  37. s_start = s_start < 0 ? 0 : s_start;
  38. var _xs = zs.substr(s_start, e);
  39. _xs = _xs.length < e ? new Array(e - _xs.length + 1).join("0") + _xs : _xs;
  40. zs = zs.substring(0, s_start);
  41. xs = _xs + xs;
  42. }
  43. zs = zs == "" ? "0" : zs;
  44. return (result[1] == "-" ? "-" : "") + zs + (xs ? "." + xs : "");
  45. };
  46. /**
  47. * 分析数字字符串
  48. *
  49. * @param {string} num NumberString
  50. * @returns object
  51. */
  52. exports.getNumbResult = function (num) {
  53. var result = REG_NUMBER.exec(num.toString());
  54. if (!result && REG_E.test(num.toString())) {
  55. result = REG_NUMBER.exec(e2ten(num.toString()));
  56. }
  57. if (result) {
  58. return {
  59. int: result[2],
  60. decimal: result[4],
  61. minus: result[1] == "-",
  62. num: result.slice(1, 3).join('')
  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. * @param {object} obj
  86. * @param {string} key
  87. * @returns
  88. */
  89. var hasAttr = exports.hasAttr = function (obj, key) {
  90. return Object.prototype.hasOwnProperty.call(obj, key);
  91. };
  92. /**
  93. * 扩展对像(浅复制)
  94. *
  95. * @param {object} obj
  96. * @param {object} obj1
  97. * @returns
  98. */
  99. exports.extend = function (obj) {
  100. var name
  101. , target = arguments[0] || {};
  102. var objs = Array.prototype.slice.call(arguments, 1);
  103. for (var i = 0; i < objs.length; i++) {
  104. var _obj = objs[i];
  105. for (name in _obj) {
  106. if (hasAttr(_obj, name)) {
  107. target[name] = _obj[name];
  108. }
  109. }
  110. }
  111. return target;
  112. };
  113. /**
  114. * 获取真实数位
  115. *
  116. * @param {number} index 中文单位的索引
  117. */
  118. exports.getDigit = function (index) {
  119. return index >= 5 ? (index - 4) * 4 + 4 : index;
  120. };
  121. /**
  122. * 往数组头部插入0
  123. *
  124. * @param {array} arr
  125. * @param {number} n
  126. */
  127. exports.unshiftZero = function (arr, n) {
  128. if (n == null) n = 1;
  129. if (n <= 0) return;
  130. for (; n--;) arr.unshift(0);
  131. };
  132. /**
  133. * 清理多余"零"
  134. *
  135. * @param {any} str
  136. * @param {any} zero "零"字符
  137. * @param {any} type 清理模式 ^ - 开头, $ - 结尾, nto1 - 多个连续变一个
  138. * @returns
  139. */
  140. exports.clearZero = function (str, zero, type) {
  141. if (str == null) return "";
  142. var reg0 = ~"*.?+$^[](){}|\\/".indexOf(zero) ? "\\" + zero : zero;
  143. var arg_s = new RegExp("^" + reg0 + "+")
  144. , arg_e = new RegExp(reg0 + "+$")
  145. , arg_d = new RegExp(reg0 + "{2}", "g");
  146. str = str.toString();
  147. if (type == "^") {
  148. str = str.replace(arg_s, "");
  149. }
  150. if (!type || type == "$") {
  151. str = str.replace(arg_e, "");
  152. }
  153. if (!type || type == "nto1") {
  154. str = str.replace(arg_d, zero);
  155. }
  156. return str;
  157. };
  158. });
  159. var utils_1 = utils.e2ten;
  160. var utils_2 = utils.getNumbResult;
  161. var utils_3 = utils.centerArray;
  162. var utils_4 = utils.hasAttr;
  163. var utils_5 = utils.extend;
  164. var utils_6 = utils.getDigit;
  165. var utils_7 = utils.unshiftZero;
  166. var utils_8 = utils.clearZero;
  167. /**
  168. * 阿拉伯数字转中文数字
  169. *
  170. * @param {String} num 阿拉伯数字/字符串 , 科学记数法字符串
  171. * @param {Object} opration 转换配置
  172. * {
  173. * ww: {万万化单位 | false}
  174. * tenMin: {十的口语化 | false}
  175. * }
  176. * @returns String
  177. */
  178. function CL(num, options) {
  179. var result = utils.getNumbResult(num);
  180. if (!result) {
  181. return num;
  182. }
  183. options = options ? options : {};
  184. var ch = this.ch //数字
  185. , ch_u = this.ch_u //单位
  186. , ch_f = this.ch_f || "" //负
  187. , ch_d = this.ch_d || "." //点
  188. , n0 = ch.charAt(0); //零
  189. var _int = result.int //整数部分
  190. , _decimal = result.decimal //小数部分
  191. , _minus = result.minus; //负数标识
  192. var int = ""
  193. , dicimal = ""
  194. , minus = _minus ? ch_f : ''; //符号位
  195. var encodeInt = function encodeInt(_int, _m, _dg) {
  196. _int = utils.getNumbResult(_int).int;
  197. var int = ""
  198. , tenm = arguments.length > 1 ? arguments[1] : options.tenMin
  199. , _length = _int.length;
  200. //一位整数
  201. if (_length == 1) return ch.charAt(+_int);
  202. if (_length <= 4) { //四位及以下
  203. for (var i = 0, n = _length; n--;) {
  204. var _num = +_int.charAt(i);
  205. int += (tenm && _length == 2 && i == 0 && _num == 1) ? "" : ch.charAt(_num);
  206. int += (_num && n ? ch_u.charAt(n) : '');
  207. i++;
  208. }
  209. } else { //大数递归
  210. var d = _int.length / 4 >> 0
  211. , y = _int.length % 4;
  212. //"兆","京"等单位处理
  213. while (y == 0 || !ch_u.charAt(3 + d)) {
  214. y += 4;
  215. d--;
  216. }
  217. var _maxLeft = _int.substr(0, y), //最大单位前的数字
  218. _other = _int.substr(y); //剩余数字
  219. int = encodeInt(_maxLeft, tenm) + ch_u.charAt(3 + d)
  220. + (_other.charAt(0) == '0' ? n0 : '') //单位后有0则加零
  221. + encodeInt(_other, _other.length > 4 ? tenm : false);
  222. }
  223. int = utils.clearZero(int, n0); //修整零
  224. return int;
  225. };
  226. //转换小数部分
  227. if (_decimal) {
  228. _decimal = utils.clearZero(_decimal, "0", "$"); //去除尾部0
  229. for (var x = 0; x < _decimal.length; x++) {
  230. dicimal += ch.charAt(+_decimal.charAt(x));
  231. }
  232. dicimal = dicimal ? ch_d + dicimal : "";
  233. }
  234. //转换整数部分
  235. int = encodeInt(_int); //转换整数
  236. //超级大数的万万化
  237. if (options.ww && ch_u.length > 5) {
  238. var dw_w = ch_u.charAt(4)
  239. , dw_y = ch_u.charAt(5);
  240. var lasty = int.lastIndexOf(dw_y);
  241. if (~lasty) {
  242. int = int.substring(0, lasty).replace(new RegExp(dw_y, 'g'), dw_w + dw_w) + int.substring(lasty);
  243. }
  244. }
  245. return minus + int + dicimal;
  246. }
  247. /**
  248. * 中文数字转阿拉伯数字
  249. *
  250. * @param {string} cnnumb 中文数字字符串
  251. * @returns Number
  252. */
  253. function unCL(cnnumb) {
  254. cnnumb = cnnumb.toString();
  255. var result = cnnumb.split(this.ch_d);
  256. var _int = result[0].replace(this.ch_f, "")
  257. , _decimal = result[1]
  258. , _minus = !!~result[0].indexOf(this.ch_f);
  259. var dw_s = this.ch_u.charAt(1)
  260. , dw_w = this.ch_u.charAt(4)
  261. , dw_y = this.ch_u.charAt(5);
  262. _int = _int.replace(new RegExp(dw_w + "{2}", "g"), dw_y);
  263. var cnarr = _int.split('');
  264. var dw = 0, maxdw = 0;
  265. var rnum_a = [], num_a = [], _num_a = [];
  266. for (var i = 0; i < cnarr.length; i++) {
  267. var chr = cnarr[i];
  268. var n = 0, u = 0;
  269. if (~(n = this.ch.indexOf(chr))) {
  270. //_num = _num*10 + n;
  271. if (n > 0) _num_a.unshift(n);
  272. //_num_a.unshift(n);
  273. } else if (~(u = this.ch_u.indexOf(chr))) {
  274. var digit = utils.getDigit(u);
  275. if (dw > u) {//正常情况
  276. utils.unshiftZero(_num_a, digit);
  277. utils.centerArray(num_a, _num_a);
  278. } else if (u >= maxdw) {//后跟大单位
  279. if (i == 0) _num_a = [1];
  280. utils.centerArray(rnum_a, num_a, _num_a);
  281. if (rnum_a.length > 0) utils.unshiftZero(rnum_a, digit);
  282. maxdw = u;
  283. } else {
  284. if (_num_a.length == 0 && dw_s == chr) _num_a = [1];
  285. utils.centerArray(num_a, _num_a);
  286. utils.unshiftZero(num_a, utils.getDigit(u));
  287. dw = u;
  288. }
  289. }
  290. }
  291. utils.centerArray(rnum_a, num_a, _num_a).reverse();
  292. if (rnum_a.length == 0) rnum_a.push(0);
  293. var decimal = 0;
  294. if (_decimal) {
  295. rnum_a.push('.');
  296. decimal = '0.';
  297. for (var i = 0; i < _decimal.length; i++) {
  298. decimal += this.ch.indexOf(_decimal.charAt(i));
  299. rnum_a.push(this.ch.indexOf(_decimal.charAt(i)));
  300. }
  301. decimal = +decimal;
  302. }
  303. if (_minus) rnum_a.unshift('-');
  304. return parseFloat(rnum_a.join(''));
  305. }
  306. /**
  307. * 阿拉伯数字转金额
  308. *
  309. * @param {String} num 阿拉伯数字/字符串 , 科学记数法字符串
  310. * @param {Object} options 转换配置
  311. * {
  312. * ww:{万万化开关 | true},
  313. * unOmitYuan: {整数为0时不省略元| false},
  314. * complete:{完整金额格式 | false},
  315. * outSymbol:{是否输出金额符号 | true}
  316. * }
  317. * @returns String
  318. */
  319. function toMoney(num, options) {
  320. var def = { ww: true, complete: false, outSymbol: true, unOmitYuan: false };
  321. var result = utils.getNumbResult(num);
  322. var ch_0 = this.ch.charAt(0);
  323. options = typeof options == "object" ? options : {};
  324. if (!result) { return num; }
  325. options = utils.extend(def, options);
  326. var _int = result.int
  327. , _decimal = result.decimal || "";
  328. var t_str = options.outSymbol ? this.m_t : ""
  329. , zs_str = result.minus ? this.ch_f : ""
  330. , xs_str = "";
  331. if (options.complete) {
  332. for (var i = 1; i < this.m_u.length; i++) {
  333. xs_str += CL.call(this, _decimal.charAt(i - 1) || "0") + this.m_u.charAt(i);
  334. }
  335. zs_str += CL.call(this, _int, options) + this.m_u.charAt(0);
  336. } else {
  337. var hasYuan = options.unOmitYuan || _int !== '0';
  338. _decimal = _decimal.substr(0, this.m_u.length-1);
  339. _decimal = utils.clearZero(_decimal, "0", "$"); //去除尾部的0
  340. if (_decimal) {
  341. var mark_0;
  342. for (var i = 0; i < this.m_u.length - 1; i++) {
  343. if (_decimal.charAt(i) && _decimal.charAt(i) != "0") {
  344. xs_str += CL.call(this, _decimal.charAt(i)) + this.m_u.charAt(i + 1);
  345. mark_0 = false;
  346. }
  347. if (_decimal.charAt(i) === "0" && !mark_0) {
  348. if (i != 0 || _int !== "0") xs_str += ch_0; //当没有输出元时,小数前无需加零
  349. mark_0 = true;
  350. }
  351. }
  352. //if(_num == "0"){xs_str = utils.clearZero(xs_str,ch_0,"^")}
  353. }
  354. if (hasYuan || !xs_str) {
  355. zs_str += CL.call(this, _int, options) + this.m_u.charAt(0) + (result.decimal ? "" : this.m_z);
  356. }
  357. // if(result.minus) t_str += this.ch_f;
  358. }
  359. return t_str + zs_str + xs_str;
  360. }
  361. var src = {
  362. CL: CL,
  363. unCL: unCL,
  364. toMoney: toMoney
  365. };
  366. function getNzhObjByLang(lang_s, lang_b) {
  367. return {
  368. encodeS: function (num, options) {
  369. options = utils.extend({ ww: true, tenMin: true }, options);
  370. return src.CL.call(lang_s, num, options);
  371. },
  372. encodeB: function (num, options) {
  373. options = utils.extend({ ww: true }, options);
  374. return src.CL.call(lang_b, num, options);
  375. },
  376. decodeS: function () {
  377. return src.unCL.apply(lang_s, arguments);
  378. },
  379. decodeB: function () {
  380. return src.unCL.apply(lang_b, arguments);
  381. },
  382. toMoney: function (num, options) {
  383. options = utils.extend({ ww: true }, options);
  384. return src.toMoney.call(lang_b, num, options);
  385. }
  386. }
  387. }
  388. var autoGet = getNzhObjByLang;
  389. var cn_s = {
  390. ch: '零一二三四五六七八九'
  391. ,ch_u: '个十百千万亿'
  392. ,ch_f: '负'
  393. ,ch_d: '点'
  394. };
  395. var cn_b = {
  396. ch: '零壹贰叁肆伍陆柒捌玖'
  397. ,ch_u: '个拾佰仟万亿'
  398. ,ch_f: '负'
  399. ,ch_d: '点'
  400. ,m_t: '人民币'
  401. ,m_z: '整'
  402. ,m_u: '元角分'
  403. };
  404. var langs = {
  405. s: cn_s,
  406. b: cn_b,
  407. };
  408. var cn = autoGet(langs.s, langs.b);
  409. return cn;
  410. })));