| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- const hexRegex = /^[-+]?0x[a-fA-F0-9]+$/;
- const numRegex = /^([\-\+])?(0*)([0-9]*(\.[0-9]*)?)$/;
- // const octRegex = /^0x[a-z0-9]+/;
- // const binRegex = /0x[a-z0-9]+/;
-
- const consider = {
- hex : true,
- // oct: false,
- leadingZeros: true,
- decimalPoint: "\.",
- eNotation: true,
- //skipLike: /regex/
- };
- export default function toNumber(str, options = {}){
- options = Object.assign({}, consider, options );
- if(!str || typeof str !== "string" ) return str;
-
- let trimmedStr = str.trim();
-
- if(options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str;
- else if(str==="0") return 0;
- else if (options.hex && hexRegex.test(trimmedStr)) {
- return parse_int(trimmedStr, 16);
- // }else if (options.oct && octRegex.test(str)) {
- // return Number.parseInt(val, 8);
- }else if (trimmedStr.search(/.+[eE].+/)!== -1) { //eNotation
- return resolveEnotation(str,trimmedStr,options);
- // }else if (options.parseBin && binRegex.test(str)) {
- // return Number.parseInt(val, 2);
- }else{
- //separate negative sign, leading zeros, and rest number
- const match = numRegex.exec(trimmedStr);
- // +00.123 => [ , '+', '00', '.123', ..
- if(match){
- const sign = match[1] || "";
- const leadingZeros = match[2];
- let numTrimmedByZeros = trimZeros(match[3]); //complete num without leading zeros
- const decimalAdjacentToLeadingZeros = sign ? // 0., -00., 000.
- str[leadingZeros.length+1] === "."
- : str[leadingZeros.length] === ".";
- //trim ending zeros for floating number
- if(!options.leadingZeros //leading zeros are not allowed
- && (leadingZeros.length > 1
- || (leadingZeros.length === 1 && !decimalAdjacentToLeadingZeros))){
- // 00, 00.3, +03.24, 03, 03.24
- return str;
- }
- else{//no leading zeros or leading zeros are allowed
- const num = Number(trimmedStr);
- const parsedStr = String(num);
- if( num === 0) return num;
- if(parsedStr.search(/[eE]/) !== -1){ //given number is long and parsed to eNotation
- if(options.eNotation) return num;
- else return str;
- }else if(trimmedStr.indexOf(".") !== -1){ //floating number
- if(parsedStr === "0") return num; //0.0
- else if(parsedStr === numTrimmedByZeros) return num; //0.456. 0.79000
- else if( parsedStr === `${sign}${numTrimmedByZeros}`) return num;
- else return str;
- }
-
- let n = leadingZeros? numTrimmedByZeros : trimmedStr;
- if(leadingZeros){
- // -009 => -9
- return (n === parsedStr) || (sign+n === parsedStr) ? num : str
- }else {
- // +9
- return (n === parsedStr) || (n === sign+parsedStr) ? num : str
- }
- }
- }else{ //non-numeric string
- return str;
- }
- }
- }
- const eNotationRegx = /^([-+])?(0*)(\d*(\.\d*)?[eE][-\+]?\d+)$/;
- function resolveEnotation(str,trimmedStr,options){
- if(!options.eNotation) return str;
- const notation = trimmedStr.match(eNotationRegx);
- if(notation){
- let sign = notation[1] || "";
- const eChar = notation[3].indexOf("e") === -1 ? "E" : "e";
- const leadingZeros = notation[2];
- const eAdjacentToLeadingZeros = sign ? // 0E.
- str[leadingZeros.length+1] === eChar
- : str[leadingZeros.length] === eChar;
- if(leadingZeros.length > 1 && eAdjacentToLeadingZeros) return str;
- else if(leadingZeros.length === 1
- && (notation[3].startsWith(`.${eChar}`) || notation[3][0] === eChar)){
- return Number(trimmedStr);
- }else if(options.leadingZeros && !eAdjacentToLeadingZeros){ //accept with leading zeros
- //remove leading 0s
- trimmedStr = (notation[1] || "") + notation[3];
- return Number(trimmedStr);
- }else return str;
- }else{
- return str;
- }
- }
- /**
- *
- * @param {string} numStr without leading zeros
- * @returns
- */
- function trimZeros(numStr){
- if(numStr && numStr.indexOf(".") !== -1){//float
- numStr = numStr.replace(/0+$/, ""); //remove ending zeros
- if(numStr === ".") numStr = "0";
- else if(numStr[0] === ".") numStr = "0"+numStr;
- else if(numStr[numStr.length-1] === ".") numStr = numStr.substring(0,numStr.length-1);
- return numStr;
- }
- return numStr;
- }
- function parse_int(numStr, base){
- //polyfill
- if(parseInt) return parseInt(numStr, base);
- else if(Number.parseInt) return Number.parseInt(numStr, base);
- else if(window && window.parseInt) return window.parseInt(numStr, base);
- else throw new Error("parseInt, Number.parseInt, window.parseInt are not supported")
- }
|