strnum.js 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. const hexRegex = /^[-+]?0x[a-fA-F0-9]+$/;
  2. const numRegex = /^([\-\+])?(0*)(\.[0-9]+([eE]\-?[0-9]+)?|[0-9]+(\.[0-9]+([eE]\-?[0-9]+)?)?)$/;
  3. // const octRegex = /0x[a-z0-9]+/;
  4. // const binRegex = /0x[a-z0-9]+/;
  5. //polyfill
  6. if (!Number.parseInt && window.parseInt) {
  7. Number.parseInt = window.parseInt;
  8. }
  9. if (!Number.parseFloat && window.parseFloat) {
  10. Number.parseFloat = window.parseFloat;
  11. }
  12. const consider = {
  13. hex : true,
  14. leadingZeros: true,
  15. decimalPoint: "\.",
  16. eNotation: true
  17. //skipLike: /regex/
  18. };
  19. function toNumber(str, options = {}){
  20. // const options = Object.assign({}, consider);
  21. // if(opt.leadingZeros === false){
  22. // options.leadingZeros = false;
  23. // }else if(opt.hex === false){
  24. // options.hex = false;
  25. // }
  26. options = Object.assign({}, consider, options );
  27. if(!str || typeof str !== "string" ) return str;
  28. let trimmedStr = str.trim();
  29. // if(trimmedStr === "0.0") return 0;
  30. // else if(trimmedStr === "+0.0") return 0;
  31. // else if(trimmedStr === "-0.0") return -0;
  32. if(options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str;
  33. else if (options.hex && hexRegex.test(trimmedStr)) {
  34. return Number.parseInt(trimmedStr, 16);
  35. // } else if (options.parseOct && octRegex.test(str)) {
  36. // return Number.parseInt(val, 8);
  37. // }else if (options.parseBin && binRegex.test(str)) {
  38. // return Number.parseInt(val, 2);
  39. }else{
  40. //separate negative sign, leading zeros, and rest number
  41. const match = numRegex.exec(trimmedStr);
  42. if(match){
  43. const sign = match[1];
  44. const leadingZeros = match[2];
  45. let numTrimmedByZeros = trimZeros(match[3]); //complete num without leading zeros
  46. //trim ending zeros for floating number
  47. const eNotation = match[4] || match[6];
  48. if(!options.leadingZeros && leadingZeros.length > 0 && sign && trimmedStr[2] !== ".") return str; //-0123
  49. else if(!options.leadingZeros && leadingZeros.length > 0 && !sign && trimmedStr[1] !== ".") return str; //0123
  50. else{//no leading zeros or leading zeros are allowed
  51. const num = Number(trimmedStr);
  52. const numStr = "" + num;
  53. if(numStr.search(/[eE]/) !== -1){ //given number is long and parsed to eNotation
  54. if(options.eNotation) return num;
  55. else return str;
  56. }else if(eNotation){ //given number has enotation
  57. if(options.eNotation) return num;
  58. else return str;
  59. }else if(trimmedStr.indexOf(".") !== -1){ //floating number
  60. // const decimalPart = match[5].substr(1);
  61. // const intPart = trimmedStr.substr(0,trimmedStr.indexOf("."));
  62. // const p = numStr.indexOf(".");
  63. // const givenIntPart = numStr.substr(0,p);
  64. // const givenDecPart = numStr.substr(p+1);
  65. if(numStr === "0" && (numTrimmedByZeros === "") ) return num; //0.0
  66. else if(numStr === numTrimmedByZeros) return num; //0.456. 0.79000
  67. else if( sign && numStr === "-"+numTrimmedByZeros) return num;
  68. else return str;
  69. }
  70. if(leadingZeros){
  71. // if(numTrimmedByZeros === numStr){
  72. // if(options.leadingZeros) return num;
  73. // else return str;
  74. // }else return str;
  75. if(numTrimmedByZeros === numStr) return num;
  76. else if(sign+numTrimmedByZeros === numStr) return num;
  77. else return str;
  78. }
  79. if(trimmedStr === numStr) return num;
  80. else if(trimmedStr === sign+numStr) return num;
  81. // else{
  82. // //number with +/- sign
  83. // trimmedStr.test(/[-+][0-9]);
  84. // }
  85. return str;
  86. }
  87. // else if(!eNotation && trimmedStr && trimmedStr !== Number(trimmedStr) ) return str;
  88. }else{ //non-numeric string
  89. return str;
  90. }
  91. }
  92. }
  93. /**
  94. *
  95. * @param {string} numStr without leading zeros
  96. * @returns
  97. */
  98. function trimZeros(numStr){
  99. if(numStr && numStr.indexOf(".") !== -1){//float
  100. numStr = numStr.replace(/0+$/, ""); //remove ending zeros
  101. if(numStr === ".") numStr = "0";
  102. else if(numStr[0] === ".") numStr = "0"+numStr;
  103. else if(numStr[numStr.length-1] === ".") numStr = numStr.substr(0,numStr.length-1);
  104. return numStr;
  105. }
  106. return numStr;
  107. }
  108. module.exports = toNumber