JavaScript:解析字符串布尔值? [复制]
Posted
技术标签:
【中文标题】JavaScript:解析字符串布尔值? [复制]【英文标题】:JavaScript: Parsing a string Boolean value? [duplicate] 【发布时间】:2011-07-10 07:10:43 【问题描述】:javascript 有 parseInt()
和 parseFloat()
,但据我所知,在全局范围内没有 parseBool
或 parseBoolean
方法。
我需要一个方法,该方法接受具有“true”或“false”等值的字符串并返回 JavaScript Boolean
。
这是我的实现:
function parseBool(value)
return (typeof value === "undefined") ?
false :
// trim using jQuery.trim()'s source
value.replace(/^\s+|\s+$/g, "").toLowerCase() === "true";
这是一个好功能吗?请给我您的反馈。
谢谢!
【问题讨论】:
如果您只是在寻找代码审查,您也可以在 codereview.stackexchange.com 上发布您的代码... 见***.com/questions/263965/… 【参考方案1】:我倾向于用三元 if 做一个单行。
var bool_value = value == "true" ? true : false
编辑:更快的方法是简单地避免使用逻辑语句,而只使用表达式本身:
var bool_value = value == 'true';
这是因为value == 'true'
是根据value
变量是否是'true'
的字符串来评估的。如果是,则整个表达式变为true
,如果不是,则变为false
,然后在评估后将该结果分配给bool_value
。
【讨论】:
为什么不进一步缩短它呢?var bool_value = value == "true"
做同样的事情 :)
三元表达式在这里可能很有用,以处理传递 null/undefined/empty 的情况:bool_value = value ? (value.toLowerCase() == "true") : false
我使用以下三元:!value ||价值==='假'?假:真;它将正确捕获以下内容:false、true、“false”、“true”、0、1、“”和未定义
较短的方式:var bool = !!value
我通常认为,当有人说他们想要“将字符串解析为布尔值”时,他们的意思是他们想要将字符串“false”映射到布尔值 false。然而在 javascript 中,!!'false' 产生布尔值 true。如果您不相信我,请在您喜欢的浏览器或 nodeJS repl 中打开 javascript 控制台并自己尝试。如果原始海报可以接受这种将“假”变为真的“解析”,那么我想!很好,但这肯定不是我所期望的解析器的行为。【参考方案2】:
您可以为此使用 JSON.parse:
JSON.parse("true"); //returns boolean true
【讨论】:
不处理混合大小写JSON.parse("True")
或非 JSON 语法,例如JSON.parse("x")
这必须是公认的答案
@AndrewL 你可能会做 JSON.parse("True".toLowerCase()) 用你的变量替换“True”【参考方案3】:
这取决于您希望该功能如何工作。
如果您只想测试字符串中的单词“true”,并将任何不包含它的字符串(或非字符串)定义为 false,那么最简单的方法可能是:
function parseBoolean(str)
return /true/i.test(str);
如果您希望确保整个字符串都是 true,您可以这样做:
function parseBoolean(str)
return /^true$/i.test(str);
【讨论】:
本机工作的方式绝对是愚蠢的。布尔函数应该执行您的示例中的后者。如果需要查看一个字符串是否包含单词 true 或 false,那么您应该检查索引是否 > 0。 这与正则表达式匹配有大量开销,而不是简单地检查字符串是否包含'true'。 @Soviut:非常正确,RGB 解决方案更受欢迎【参考方案4】:您可以尝试以下方法:
function parseBool(val)
if ((typeof val === 'string' && (val.toLowerCase() === 'true' || val.toLowerCase() === 'yes')) || val === 1)
return true;
else if ((typeof val === 'string' && (val.toLowerCase() === 'false' || val.toLowerCase() === 'no')) || val === 0)
return false;
return null;
如果是有效值,则返回等效的 bool 值,否则返回 null。
【讨论】:
这几乎成功了,我对其进行了一些调整以使其正常工作('string'
周围的单引号):function parseBool(val) if ((typeof val == 'string' && (val.toLowerCase() === 'true' || val.toLowerCase() === 'yes')) || val === 1) return true; else if ((typeof val === 'string' && (val.toLowerCase() === 'false' || val.toLowerCase() === 'no')) || val === 0) return false; return null;
@delliottg 更新了 string 上的引号。【参考方案5】:
您可以使用 JSON.parse 或 jQuery.parseJSON 并使用以下方法查看它是否返回 true:
function test (input)
try
return !!$.parseJSON(input.toLowerCase());
catch (e)
【讨论】:
对我来说看起来有点危险。例如,test("\"false\"")
将返回 true
作为非空字符串。这不太可能,但却是一个非常不明显的错误来源。
如果输入的是无效的JSON,这个函数会返回undefined
。
@idealmaschine:这对我来说似乎是件好事。这是你想说的,还是批评?
@RoToRa:好点。但是不知道数据就很难知道“\”false\””应该是真还是假——那么“\”not true\””或“\”no\””或“yes”呢?一种可能性是为除显式 true 或 false 之外的所有内容返回 undefined,或者使用通常的 JavaScript 或 JSON 语义,或者使用一些适合给定应用程序的自定义逻辑。如果甚至很难找到两种在什么是真什么是假上达成一致的编程语言,也很难制定一个通用的解决方案。
@idealmaschine:如果您想为无效 JSON 设置 false,可以在 catch 块中添加 return false;
,但请记住,在 JavaScript 中 undefined 也是虚假的,因此它可能并不重要,具体取决于关于你如何使用它。【参考方案6】:
我个人认为这不好,您的函数将无效值“隐藏”为 false
并且 - 根据您的用例 - 不会为 "1"
返回 true
。
另一个问题可能是它对任何不是字符串的东西都会产生呕吐声。
我会使用这样的东西:
function parseBool(value)
if (typeof value === "string")
value = value.replace(/^\s+|\s+$/g, "").toLowerCase();
if (value === "true" || value === "false")
return value === "true";
return; // returns undefined
并根据用例扩展它以区分 "0"
和 "1"
。
(也许有一种方法可以只与"true"
比较一次,但我现在想不出什么。)
【讨论】:
很抱歉挖掘了非常旧的代码,但为什么不只是return true;
?为什么return value === "true";
?我的意思是,你已经检查过它是否有效,对吧?
@Metagrapher 如果我只是return true
,它将返回true,如果值也是"false"
。
我不知道我在阅读该代码时出了什么问题。对不起。哈哈,谢谢你的清晰。【参考方案7】:
您可以添加此代码:
function parseBool(str)
if (str.length == null)
return str == 1 ? true : false;
else
return str == "true" ? true : false;
像这样工作:
parseBool(1) //true
parseBool(0) //false
parseBool("true") //true
parseBool("false") //false
【讨论】:
我看到三元像这样使用了很多,但它们不是必需的。你可以做return (str === 1)
【参考方案8】:
为什么不保持简单?
var parseBool = function(str)
if (typeof str === 'string' && str.toLowerCase() == 'true')
return true;
return (parseInt(str) > 0);
【讨论】:
【参考方案9】:小心木眼。 看了这么多代码,觉得有义务发一下:
让我们从最短但非常严格的方式开始:
var str = "true";
var mybool = JSON.parse(str);
并以一种适当的、更宽容的方式结束:
var parseBool = function(str)
// console.log(typeof str);
// strict: JSON.parse(str)
if(str == null)
return false;
if (typeof str === 'boolean')
if(str === true)
return true;
return false;
if(typeof str === 'string')
if(str == "")
return false;
str = str.replace(/^\s+|\s+$/g, '');
if(str.toLowerCase() == 'true' || str.toLowerCase() == 'yes')
return true;
str = str.replace(/,/g, '.');
str = str.replace(/^\s*\-\s*/g, '-');
// var isNum = string.match(/^[0-9]+$/) != null;
// var isNum = /^\d+$/.test(str);
if(!isNaN(str))
return (parseFloat(str) != 0);
return false;
测试:
var array_1 = new Array(true, 1, "1",-1, "-1", " - 1", "true", "TrUe", " true ", " TrUe", 1/0, "1.5", "1,5", 1.5, 5, -3, -0.1, 0.1, " - 0.1", Infinity, "Infinity", -Infinity, "-Infinity"," - Infinity", " yEs");
var array_2 = new Array(null, "", false, "false", " false ", " f alse", "FaLsE", 0, "00", "1/0", 0.0, "0.0", "0,0", "100a", "1 00", " 0 ", 0.0, "0.0", -0.0, "-0.0", " -1a ", "abc");
for(var i =0; i < array_1.length;++i) console.log("array_1["+i+"] ("+array_1[i]+"): " + parseBool(array_1[i]));
for(var i =0; i < array_2.length;++i) console.log("array_2["+i+"] ("+array_2[i]+"): " + parseBool(array_2[i]));
for(var i =0; i < array_1.length;++i) console.log(parseBool(array_1[i]));
for(var i =0; i < array_2.length;++i) console.log(parseBool(array_2[i]));
【讨论】:
【参考方案10】:最后但并非最不重要的是,一种使用默认值的简单有效的方法:
ES5
function parseBool(value, defaultValue)
return (value == 'true' || value == 'false' || value === true || value === false) && JSON.parse(value) || defaultValue;
ES6 ,更短的一个衬里
const parseBool = (value, defaultValue) => ['true', 'false', true, false].includes(value) && JSON.parse(value) || defaultValue
JSON.parse 可以高效地解析布尔值
【讨论】:
【参考方案11】:我喜欢 RoToRa 提供的解决方案(尝试解析给定的值,如果它有任何布尔含义,否则 - 不要)。尽管如此,我还是想提供一些小的修改,让它或多或少像 C# 中的 Boolean.TryParse 那样工作,它支持 out
参数。在 JavaScript 中可以通过以下方式实现:
var BoolHelpers =
tryParse: function (value)
if (typeof value == 'boolean' || value instanceof Boolean)
return value;
if (typeof value == 'string' || value instanceof String)
value = value.trim().toLowerCase();
if (value === 'true' || value === 'false')
return value === 'true';
return error: true, msg: 'Parsing error. Given value has no boolean meaning.'
用法:
var result = BoolHelpers.tryParse("false");
if (result.error) alert(result.msg);
【讨论】:
【参考方案12】:stringjs 有一个 toBoolean() 方法:
http://stringjs.com/#methods/toboolean-tobool
S('true').toBoolean() //true
S('false').toBoolean() //false
S('hello').toBoolean() //false
S(true).toBoolean() //true
S('on').toBoolean() //true
S('yes').toBoolean() //true
S('TRUE').toBoolean() //true
S('TrUe').toBoolean() //true
S('YES').toBoolean() //true
S('ON').toBoolean() //true
S('').toBoolean() //false
S(undefined).toBoolean() //false
S('undefined').toBoolean() //false
S(null).toBoolean() //false
S(false).toBoolean() //false
S().toBoolean() //false
S(1).toBoolean() //true
S(-1).toBoolean() //false
S(0).toBoolean() //false
【讨论】:
【参考方案13】:我无耻地将Apache Common's toBoolean
转换为 JavaScript:
JSFiddle:https://jsfiddle.net/m2efvxLm/1/
代码:
function toBoolean(str)
if (str == "true")
return true;
if (!str)
return false;
switch (str.length)
case 1:
var ch0 = str.charAt(0);
if (ch0 == 'y' || ch0 == 'Y' ||
ch0 == 't' || ch0 == 'T' ||
ch0 == '1')
return true;
if (ch0 == 'n' || ch0 == 'N' ||
ch0 == 'f' || ch0 == 'F' ||
ch0 == '0')
return false;
break;
case 2:
var ch0 = str.charAt(0);
var ch1 = str.charAt(1);
if ((ch0 == 'o' || ch0 == 'O') &&
(ch1 == 'n' || ch1 == 'N') )
return true;
if ((ch0 == 'n' || ch0 == 'N') &&
(ch1 == 'o' || ch1 == 'O') )
return false;
break;
case 3:
var ch0 = str.charAt(0);
var ch1 = str.charAt(1);
var ch2 = str.charAt(2);
if ((ch0 == 'y' || ch0 == 'Y') &&
(ch1 == 'e' || ch1 == 'E') &&
(ch2 == 's' || ch2 == 'S') )
return true;
if ((ch0 == 'o' || ch0 == 'O') &&
(ch1 == 'f' || ch1 == 'F') &&
(ch2 == 'f' || ch2 == 'F') )
return false;
break;
case 4:
var ch0 = str.charAt(0);
var ch1 = str.charAt(1);
var ch2 = str.charAt(2);
var ch3 = str.charAt(3);
if ((ch0 == 't' || ch0 == 'T') &&
(ch1 == 'r' || ch1 == 'R') &&
(ch2 == 'u' || ch2 == 'U') &&
(ch3 == 'e' || ch3 == 'E') )
return true;
break;
case 5:
var ch0 = str.charAt(0);
var ch1 = str.charAt(1);
var ch2 = str.charAt(2);
var ch3 = str.charAt(3);
var ch4 = str.charAt(4);
if ((ch0 == 'f' || ch0 == 'F') &&
(ch1 == 'a' || ch1 == 'A') &&
(ch2 == 'l' || ch2 == 'L') &&
(ch3 == 's' || ch3 == 'S') &&
(ch4 == 'e' || ch4 == 'E') )
return false;
break;
default:
break;
return false;
console.log(toBoolean("yEs")); // true
console.log(toBoolean("yES")); // true
console.log(toBoolean("no")); // false
console.log(toBoolean("NO")); // false
console.log(toBoolean("on")); // true
console.log(toBoolean("oFf")); // false
Inspect this element, and view the console output.
【讨论】:
对我来说似乎很荒谬,为什么他们不包括typeof === 'boolean'
的案例,以防有人真的通过 true
或 false
。
没有必要,因为Java是一种强类型语言。【参考方案14】:
足以使用 eval javascript 函数将字符串转换为布尔值
eval('true')
eval('false')
【讨论】:
Eval 破坏了很多优化,导致代码变慢,难以调试和维护。如果可以,永远不要使用它 - 有更好的方法来解决这个问题,请参阅其他答案。 在这种情况下,您列出的所有内容都不是关键和适用的。 Jens 您提到的所有内容都不适用于这种情况,但没有提到真正重要的问题,即安全性。 eval 会导致 js 注入,因此如果您不能信任输入源,请不要使用它,并且如果您使用的是浏览器,那么您几乎无法信任它。 JSON.parse 是安全的方式(不确定是否最快)。以上是关于JavaScript:解析字符串布尔值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
在 JavaScript 中使用 (!!!) 运算符? [复制]