125 lines
4.7 KiB
JavaScript
125 lines
4.7 KiB
JavaScript
|
const hexRegex = /^[-+]?0x[a-fA-F0-9]+$/;
|
||
|
const numRegex = /^([\-\+])?(0*)(\.[0-9]+([eE]\-?[0-9]+)?|[0-9]+(\.[0-9]+([eE]\-?[0-9]+)?)?)$/;
|
||
|
// const octRegex = /0x[a-z0-9]+/;
|
||
|
// const binRegex = /0x[a-z0-9]+/;
|
||
|
|
||
|
|
||
|
//polyfill
|
||
|
if (!Number.parseInt && window.parseInt) {
|
||
|
Number.parseInt = window.parseInt;
|
||
|
}
|
||
|
if (!Number.parseFloat && window.parseFloat) {
|
||
|
Number.parseFloat = window.parseFloat;
|
||
|
}
|
||
|
|
||
|
|
||
|
const consider = {
|
||
|
hex : true,
|
||
|
leadingZeros: true,
|
||
|
decimalPoint: "\.",
|
||
|
eNotation: true
|
||
|
//skipLike: /regex/
|
||
|
};
|
||
|
|
||
|
function toNumber(str, options = {}){
|
||
|
// const options = Object.assign({}, consider);
|
||
|
// if(opt.leadingZeros === false){
|
||
|
// options.leadingZeros = false;
|
||
|
// }else if(opt.hex === false){
|
||
|
// options.hex = false;
|
||
|
// }
|
||
|
|
||
|
options = Object.assign({}, consider, options );
|
||
|
if(!str || typeof str !== "string" ) return str;
|
||
|
|
||
|
let trimmedStr = str.trim();
|
||
|
// if(trimmedStr === "0.0") return 0;
|
||
|
// else if(trimmedStr === "+0.0") return 0;
|
||
|
// else if(trimmedStr === "-0.0") return -0;
|
||
|
|
||
|
if(options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str;
|
||
|
else if (options.hex && hexRegex.test(trimmedStr)) {
|
||
|
return Number.parseInt(trimmedStr, 16);
|
||
|
// } else if (options.parseOct && octRegex.test(str)) {
|
||
|
// return Number.parseInt(val, 8);
|
||
|
// }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);
|
||
|
if(match){
|
||
|
const sign = match[1];
|
||
|
const leadingZeros = match[2];
|
||
|
let numTrimmedByZeros = trimZeros(match[3]); //complete num without leading zeros
|
||
|
//trim ending zeros for floating number
|
||
|
|
||
|
const eNotation = match[4] || match[6];
|
||
|
if(!options.leadingZeros && leadingZeros.length > 0 && sign && trimmedStr[2] !== ".") return str; //-0123
|
||
|
else if(!options.leadingZeros && leadingZeros.length > 0 && !sign && trimmedStr[1] !== ".") return str; //0123
|
||
|
else{//no leading zeros or leading zeros are allowed
|
||
|
const num = Number(trimmedStr);
|
||
|
const numStr = "" + num;
|
||
|
if(numStr.search(/[eE]/) !== -1){ //given number is long and parsed to eNotation
|
||
|
if(options.eNotation) return num;
|
||
|
else return str;
|
||
|
}else if(eNotation){ //given number has enotation
|
||
|
if(options.eNotation) return num;
|
||
|
else return str;
|
||
|
}else if(trimmedStr.indexOf(".") !== -1){ //floating number
|
||
|
// const decimalPart = match[5].substr(1);
|
||
|
// const intPart = trimmedStr.substr(0,trimmedStr.indexOf("."));
|
||
|
|
||
|
|
||
|
// const p = numStr.indexOf(".");
|
||
|
// const givenIntPart = numStr.substr(0,p);
|
||
|
// const givenDecPart = numStr.substr(p+1);
|
||
|
if(numStr === "0" && (numTrimmedByZeros === "") ) return num; //0.0
|
||
|
else if(numStr === numTrimmedByZeros) return num; //0.456. 0.79000
|
||
|
else if( sign && numStr === "-"+numTrimmedByZeros) return num;
|
||
|
else return str;
|
||
|
}
|
||
|
|
||
|
if(leadingZeros){
|
||
|
// if(numTrimmedByZeros === numStr){
|
||
|
// if(options.leadingZeros) return num;
|
||
|
// else return str;
|
||
|
// }else return str;
|
||
|
if(numTrimmedByZeros === numStr) return num;
|
||
|
else if(sign+numTrimmedByZeros === numStr) return num;
|
||
|
else return str;
|
||
|
}
|
||
|
|
||
|
if(trimmedStr === numStr) return num;
|
||
|
else if(trimmedStr === sign+numStr) return num;
|
||
|
// else{
|
||
|
// //number with +/- sign
|
||
|
// trimmedStr.test(/[-+][0-9]);
|
||
|
|
||
|
// }
|
||
|
return str;
|
||
|
}
|
||
|
// else if(!eNotation && trimmedStr && trimmedStr !== Number(trimmedStr) ) return str;
|
||
|
|
||
|
}else{ //non-numeric string
|
||
|
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.substr(0,numStr.length-1);
|
||
|
return numStr;
|
||
|
}
|
||
|
return numStr;
|
||
|
}
|
||
|
module.exports = toNumber
|