JavaScript中如何测试一个字符串是否为有效的浮点数

10

我想测试一个字符串是否能被转换为浮点数。我一直在尝试使用parseFloat来实现这一点。

console.log(!isNaN(parseFloat("10000"))); // should return true
console.log(!isNaN(parseFloat("100T0"))); // should return false (but doesn't)

原来,parseFloat在遇到非数字字符时就停止读取字符串,并返回已经读取的部分。因此,parseFloat("100T0")实际上返回100而不是NaN
有什么更好的JS测试方法可以判断一个字符串是否可以转换为浮点数吗?
5个回答

9
使用 parseFloat() 方法并不能得到您期望的结果,因为它会尝试解析 100T0 并返回 100,所以这是一个有效的 Number
相比使用 isNaN() 方法,您可以使用正则表达式来检查给定的字符串是否仅由数字组成。
下面是您需要使用的正则表达式 /^\-?[0-9]+(e[0-9]+)?(\.[0-9]+)?$/,您可以按照以下方式编写代码:
function isItNumber(str) {
  return /^\-?[0-9]+(e[0-9]+)?(\.[0-9]+)?$/.test(str);
}

演示:

function isItNumber(str) {
  return /^\-?[0-9]+(e[0-9]+)?(\.[0-9]+)?$/.test(str);
}

console.log(isItNumber("10000")) // should return true
console.log(isItNumber("100T0"))
console.log(isItNumber("10e5"))
console.log(isItNumber("100.50"))


虽然我在问题中没有注明,但它需要处理小数点。 - rvictordelta
@rvictordelta 我编辑了答案,并更新了正则表达式。 - cнŝdk

9

在 JavaScript 中,默认情况下没有内置的操作可以匹配一个合理的“这个字符串是一个数字吗”的定义(至少对我来说是这样)。您可以使用 Number、一元的 + 或隐式转换(直接将字符串传递给 isNaN),但需要注意它们都会执行相同的操作,包括将 "" 视为 0

// Number
console.log(!isNaN(Number("10000"))); // true
console.log(!isNaN(Number("100T0"))); // false
console.log(!isNaN(Number("")));      // true (!)

// Same as implicit (here triggered with a unary +)
console.log(!isNaN(+"10000")); // true
console.log(!isNaN(+"100T0")); // false
console.log(!isNaN(+""));      // true (!)


// Same as implicit
console.log(!isNaN("10000")); // true
console.log(!isNaN("100T0")); // false
console.log(!isNaN(""));      // true (!)

我的答案 关于相关问题详细介绍了您的选项。

因此,您可以使用正则表达式(确保允许科学计数法!)或事先检查 ""

function toNumber(str) {
  str = String(str).trim();
  return !str ? NaN : Number(str);
}
console.log(!isNaN(toNumber("10000"))); // true
console.log(!isNaN(toNumber("100T0"))); // false
console.log(!isNaN(toNumber("")));      // false


3
您可以尝试使用正则表达式:
> (/^-?[\d]*(\.[\d]+)?$/g).test('0');
true
> (/^-?[\d]*(\.[\d]+)?$/g).test('1000');
true
> (/^-?[\d]*(\.[\d]+)?$/g).test('10E0');
false
> (/^-?[\d]*(\.[\d]+)?$/g).test('1000.E');
false
> (/^-?[\d]*(\.[\d]+)?$/g).test('1000.1');
true
> (/^-?[\d]*(\.[\d]+)?$/g).test('1.1000');
true
> (/^-?[\d]*(\.[\d]+)?$/g).test('.1000');
true
> (/^-?[\d]*(\.[\d]+)?$/g).test('1000.');
false
> (/^-?[\d]*(\.[\d]+)?$/g).test('-.1');
true
> (/^-?[\d]*(\.[\d]+)?$/g).test('-1000.1');
true
> (/^-?[\d]*(\.[\d]+)?$/g).test('-1000');
true

使用函数:

function isValidFloat(str) {
    return (/^-?[\d]*(\.[\d]+)?$/g).test(str);
}

0

伪代码中的另一个想法

1) Loop through string substrings (imitating parseFloat)
2) Get the substring that parseFloat stops at
3) Compare this substring to the original

旧的伪代码 - 不完全可行 - 可能需要修改

你可以这样做(伪代码)

if (parseFloat (value)).toString() <> value then
   you know that the parse float only converted part of the value

基本上你的意思是说,如果转换工作“正确”,那么字符串>浮点数>(回到)字符串应该给出相同的字符串。

同意。采用新的方法进行编辑。 - Hassan Voyeau

0
你可以尝试使用正则表达式来匹配只有浮点数格式的字符串。希望这能帮到你。

const reg = /^-?([0-9]+\.[0-9]+)$/g;

console.log("Should match");
console.log("123.2".match(reg));
console.log("12.000".match(reg));
console.log("-12.000".match(reg));

console.log("Should not match");
console.log("123".match(reg));
console.log("123a123".match(reg));
console.log("1e2".match(reg));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接