strnum 1.0.4 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,25 @@
1
+ {
2
+ "version": "0.2.0",
3
+ "configurations": [
4
+ {
5
+ "type": "node",
6
+ "request": "launch",
7
+ "name": "Jasmine Tests",
8
+ "program": "${workspaceFolder}/node_modules/jasmine/bin/jasmine.js",
9
+ "args": [
10
+ "${workspaceFolder}/spec/attr_spec.js"
11
+ ],
12
+ "internalConsoleOptions": "openOnSessionStart"
13
+ },{
14
+ "type": "node",
15
+ "request": "launch",
16
+ "name": "Jasmine Tests current test file",
17
+ "program": "${workspaceFolder}/node_modules/jasmine/bin/jasmine.js",
18
+ "args": [
19
+ "${file}"
20
+ ],
21
+ "internalConsoleOptions": "openOnSessionStart"
22
+ }
23
+ ]
24
+
25
+ }
package/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+
2
+ **1.1.0 / 2025-02-20**
3
+ - fix (#9): support missing floating point and e notations
package/README.md CHANGED
@@ -1,6 +1,16 @@
1
1
  # strnum
2
2
  Parse string into Number based on configuration
3
3
 
4
+ ## Users
5
+
6
+ <a href="https://github.com/aws-amplify" target="_blank"><img src="https://avatars.githubusercontent.com/u/41077760?s=100&v=4"></a>
7
+ <a href="https://github.com/astrapay" target="_blank"><img src="https://avatars.githubusercontent.com/u/90901882?s=100&v=4"></a>
8
+ <a href="https://github.com/process-analytics" target="_blank"><img src="https://avatars.githubusercontent.com/u/60110287?s=100&v=4"></a>
9
+ <a href="https://github.com/NaturalIntelligence" target="_blank"><img src="https://avatars.githubusercontent.com/u/16322633?s=100&v=4"></a>
10
+ Many React Native projects and plugins
11
+
12
+ ## Usage
13
+
4
14
  ```bash
5
15
  npm install strnum
6
16
  ```
@@ -76,4 +86,12 @@ toNumber("1.0e-2"); //0.01)
76
86
 
77
87
  toNumber("+1212121212"); // 1212121212
78
88
  toNumber("+1212121212", { skipLike: /\+[0-9]{10}/} )); //"+1212121212"
79
- ```
89
+ ```
90
+
91
+ Supported Options
92
+ ```js
93
+ hex: true, //when hexadecimal string should be parsed
94
+ leadingZeros: true, //when number with leading zeros like 08 should be parsed. 0.0 is not impacted
95
+ eNotation: true, //when number with eNotation or number parsed in eNotation should be considered
96
+ skipLike: /regex/ //when string should not be parsed when it matches the specified regular expression
97
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "strnum",
3
- "version": "1.0.4",
3
+ "version": "1.1.0",
4
4
  "description": "Parse String to Number based on configuration",
5
5
  "main": "strnum.js",
6
6
  "scripts": {
@@ -17,5 +17,8 @@
17
17
  "url": "https://github.com/NaturalIntelligence/strnum"
18
18
  },
19
19
  "author": "Amit Gupta (https://amitkumargupta.work/)",
20
- "license": "MIT"
20
+ "license": "MIT",
21
+ "devDependencies": {
22
+ "jasmine": "^3.10.0"
23
+ }
21
24
  }
package/strnum.js CHANGED
@@ -1,50 +1,106 @@
1
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]+/;
2
+ const numRegex = /^([\-\+])?(0*)([0-9]*(\.[0-9]*)?)$/;
3
+ // const octRegex = /^0x[a-z0-9]+/;
4
4
  // const binRegex = /0x[a-z0-9]+/;
5
5
 
6
+
6
7
  const consider = {
7
8
  hex : true,
9
+ // oct: false,
8
10
  leadingZeros: true,
9
11
  decimalPoint: "\.",
12
+ eNotation: true,
10
13
  //skipLike: /regex/
11
14
  };
12
15
 
13
16
  function toNumber(str, options = {}){
14
- // const options = Object.assign({}, consider);
15
- // if(opt.leadingZeros === false){
16
- // options.leadingZeros = false;
17
- // }else if(opt.hex === false){
18
- // options.hex = false;
19
- // }
20
-
21
17
  options = Object.assign({}, consider, options );
22
18
  if(!str || typeof str !== "string" ) return str;
23
19
 
24
20
  let trimmedStr = str.trim();
25
-
21
+
26
22
  if(options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str;
27
23
  else if (options.hex && hexRegex.test(trimmedStr)) {
28
- return Number.parseInt(trimmedStr, 16);
29
- // } else if (options.parseOct && octRegex.test(str)) {
24
+ return parse_int(trimmedStr, 16);
25
+ // }else if (options.oct && octRegex.test(str)) {
30
26
  // return Number.parseInt(val, 8);
27
+ }else if (trimmedStr.search(/[eE]/)!== -1) { //eNotation
28
+ const notation = trimmedStr.match(/^([-\+])?(0*)([0-9]*(\.[0-9]*)?[eE][-\+]?[0-9]+)/);
29
+ // +00.123 => [ , '+', '00', '.123', ..
30
+ if(notation){
31
+ if(options.leadingZeros){ //accept with leading zeros
32
+ trimmedStr = (notation[1] || "") + notation[3];
33
+ }else{
34
+ if(notation[2] === "0" && notation[3][0]=== "."){ //valid number
35
+ }else{
36
+ return trimmedStr;
37
+ }
38
+ }
39
+ return options.eNotation ? Number(trimmedStr) : trimmedStr;
40
+ }else{
41
+ return trimmedStr;
42
+ }
31
43
  // }else if (options.parseBin && binRegex.test(str)) {
32
44
  // return Number.parseInt(val, 2);
33
45
  }else{
34
46
  //separate negative sign, leading zeros, and rest number
35
47
  const match = numRegex.exec(trimmedStr);
48
+ // +00.123 => [ , '+', '00', '.123', ..
36
49
  if(match){
37
- const negative = match[1];
50
+ const sign = match[1];
38
51
  const leadingZeros = match[2];
39
- const num = match[3]; //complete num
40
- const eNotation = match[4] || match[6];
41
- if(leadingZeros.length === 1 && num[0] === ".") return Number(str);
42
- else if(!options.leadingZeros && leadingZeros.length > 0) return str;
43
- else return Number(trimmedStr);
52
+ let numTrimmedByZeros = trimZeros(match[3]); //complete num without leading zeros
53
+ //trim ending zeros for floating number
54
+
55
+ if(!options.leadingZeros && leadingZeros.length > 0 && sign && trimmedStr[2] !== ".") return str; //-0123
56
+ else if(!options.leadingZeros && leadingZeros.length > 0 && !sign && trimmedStr[1] !== ".") return str; //0123
57
+ else{//no leading zeros or leading zeros are allowed
58
+ const num = Number(trimmedStr);
59
+ const numStr = "" + num;
60
+
61
+ if(numStr.search(/[eE]/) !== -1){ //given number is long and parsed to eNotation
62
+ if(options.eNotation) return num;
63
+ else return str;
64
+ }else if(trimmedStr.indexOf(".") !== -1){ //floating number
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
+
71
+ if(leadingZeros){
72
+ return (numTrimmedByZeros === numStr) || (sign+numTrimmedByZeros === numStr) ? num : str
73
+ }else {
74
+ return (trimmedStr === numStr) || (trimmedStr === sign+numStr) ? num : str
75
+ }
76
+ }
44
77
  }else{ //non-numeric string
45
78
  return str;
46
79
  }
47
80
  }
48
81
  }
49
82
 
83
+ /**
84
+ *
85
+ * @param {string} numStr without leading zeros
86
+ * @returns
87
+ */
88
+ function trimZeros(numStr){
89
+ if(numStr && numStr.indexOf(".") !== -1){//float
90
+ numStr = numStr.replace(/0+$/, ""); //remove ending zeros
91
+ if(numStr === ".") numStr = "0";
92
+ else if(numStr[0] === ".") numStr = "0"+numStr;
93
+ else if(numStr[numStr.length-1] === ".") numStr = numStr.substr(0,numStr.length-1);
94
+ return numStr;
95
+ }
96
+ return numStr;
97
+ }
98
+
99
+ function parse_int(numStr, base){
100
+ //polyfill
101
+ if(parseInt) return parseInt(numStr, base);
102
+ else if(Number.parseInt) return Number.parseInt(numStr, base);
103
+ else if(window && window.parseInt) return window.parseInt(numStr, base);
104
+ else throw new Error("parseInt, Number.parseInt, window.parseInt are not supported")
105
+ }
50
106
  module.exports = toNumber
package/strnum.test.js CHANGED
@@ -15,6 +15,7 @@ describe("Should convert all the valid numeric strings to number", () => {
15
15
  })
16
16
  it("should consider + sign", () => {
17
17
  expect(toNumber("+12")).toEqual(12);
18
+ expect(toNumber("+ 12")).toEqual("+ 12");
18
19
  expect(toNumber("12+12")).toEqual("12+12");
19
20
  expect(toNumber("1212+")).toEqual("1212+");
20
21
  })
@@ -40,9 +41,22 @@ describe("Should convert all the valid numeric strings to number", () => {
40
41
  expect(toNumber("006")).toEqual(6);
41
42
  expect(toNumber("006", { leadingZeros : true})).toEqual(6);
42
43
  expect(toNumber("006", { leadingZeros : false})).toEqual("006");
44
+
45
+ expect(toNumber("000000000000000000000000017717" , { leadingZeros : false})).toEqual("000000000000000000000000017717");
46
+ expect(toNumber("000000000000000000000000017717" , { leadingZeros : true})).toEqual(17717);
47
+ expect(toNumber("020211201030005811824") ).toEqual("020211201030005811824");
48
+ expect(toNumber("0420926189200190257681175017717") ).toEqual(4.209261892001902e+29);
43
49
  })
50
+ it("invalid floating number", () => {
51
+ expect(toNumber("20.21.030") ).toEqual("20.21.030");
52
+ expect(toNumber("0.21.030") ).toEqual("0.21.030");
53
+ expect(toNumber("0.21.") ).toEqual("0.21.");
54
+ expect(toNumber("0.")).toEqual(0);
55
+ expect(toNumber("+0.")).toEqual(0);
56
+ expect(toNumber("-0.")).toEqual(-0);
57
+ expect(toNumber("1.") ).toEqual(1);
58
+ });
44
59
  it("floating point and leading zeros", () => {
45
- expect(toNumber("0.0")).toEqual(0);
46
60
  expect(toNumber("00.00")).toEqual(0);
47
61
  expect(toNumber("0.06")).toEqual(0.06);
48
62
  expect(toNumber("00.6")).toEqual(0.6);
@@ -59,6 +73,7 @@ describe("Should convert all the valid numeric strings to number", () => {
59
73
  expect(toNumber("06.0" , { leadingZeros : false})).toEqual("06.0");
60
74
  })
61
75
  it("negative number leading zeros", () => {
76
+ expect(toNumber("+06")).toEqual(6);
62
77
  expect(toNumber("-06")).toEqual(-6);
63
78
  expect(toNumber("-06", { leadingZeros : true})).toEqual(-6);
64
79
  expect(toNumber("-06", { leadingZeros : false})).toEqual("-06");
@@ -80,9 +95,10 @@ describe("Should convert all the valid numeric strings to number", () => {
80
95
  expect(toNumber("-06.0" , { leadingZeros : false})).toEqual("-06.0");
81
96
  })
82
97
  it("long number", () => {
83
- expect(toNumber("420926189200190257681175017717") ).toEqual(4.209261892001902e+29);
84
- expect(toNumber("000000000000000000000000017717" , { leadingZeros : false})).toEqual("000000000000000000000000017717");
85
- expect(toNumber("000000000000000000000000017717" , { leadingZeros : true})).toEqual(17717);
98
+ expect(toNumber("020211201030005811824") ).toEqual("020211201030005811824");
99
+ expect(toNumber("20211201030005811824") ).toEqual("20211201030005811824");
100
+ expect(toNumber("20.211201030005811824") ).toEqual("20.211201030005811824");
101
+ expect(toNumber("0.211201030005811824") ).toEqual("0.211201030005811824");
86
102
  });
87
103
  it("scientific notation", () => {
88
104
  expect(toNumber("01.0e2" , { leadingZeros : false})).toEqual("01.0e2");
@@ -93,6 +109,13 @@ describe("Should convert all the valid numeric strings to number", () => {
93
109
 
94
110
  expect(toNumber("-1.0e2") ).toEqual(-100);
95
111
  expect(toNumber("1.0e-2")).toEqual(0.01);
112
+
113
+ expect(toNumber("420926189200190257681175017717") ).toEqual(4.209261892001902e+29);
114
+ expect(toNumber("420926189200190257681175017717" , { eNotation: false} )).toEqual("420926189200190257681175017717");
115
+
116
+ expect(toNumber("1e-2")).toEqual(0.01);
117
+ expect(toNumber("1e+2")).toEqual(100);
118
+ expect(toNumber("1.e+2")).toEqual(100);
96
119
  });
97
120
 
98
121
  it("scientific notation with upper E", () => {
@@ -120,4 +143,12 @@ describe("Should convert all the valid numeric strings to number", () => {
120
143
  it("should ignore sorrounded spaces ", () => {
121
144
  expect(toNumber(" +1212 ")).toEqual(1212);
122
145
  })
146
+
147
+ it("negative numbers", () => {
148
+ expect(toNumber("+1212")).toEqual(1212);
149
+ expect(toNumber("+12.12")).toEqual(12.12);
150
+ expect(toNumber("-12.12")).toEqual(-12.12);
151
+ expect(toNumber("-012.12")).toEqual(-12.12);
152
+ expect(toNumber("-012.12")).toEqual(-12.12);
153
+ })
123
154
  });
package/test.js ADDED
@@ -0,0 +1,6 @@
1
+ const toNumber = require("./strnum");
2
+
3
+ // console.log(toNumber("01.0e2"))
4
+ console.log(toNumber("-06"))
5
+ // console.log(toNumber("+01.0e2"))
6
+ // console.log(toNumber("+001.0e2"))