JavaScript:解析字符串布尔值? [复制]

Posted

技术标签:

【中文标题】JavaScript:解析字符串布尔值? [复制]【英文标题】:JavaScript: Parsing a string Boolean value? [duplicate] 【发布时间】:2011-07-10 07:10:43 【问题描述】:

javascriptparseInt()parseFloat(),但据我所知,在全局范围内没有 parseBoolparseBoolean 方法。

我需要一个方法,该方法接受具有“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' 的案例,以防有人真的通过 truefalse 没有必要,因为Java是一种强类型语言。【参考方案14】:

足以使用 eval javascript 函数将字符串转换为布尔值

eval('true')  
eval('false')

【讨论】:

Eval 破坏了很多优化,导致代码变慢,难以调试和维护。如果可以,永远不要使用它 - 有更好的方法来解决这个问题,请参阅其他答案。 在这种情况下,您列出的所有内容都不是关键和适用的。 Jens 您提到的所有内容都不适用于这种情况,但没有提到真正重要的问题,即安全性。 eval 会导致 js 注入,因此如果您不能信任输入源,请不要使用它,并且如果您使用的是浏览器,那么您几乎无法信任它。 JSON.parse 是安全的方式(不确定是否最快)。

以上是关于JavaScript:解析字符串布尔值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

检查是不是设置了 Javascript 布尔值? [复制]

在 JavaScript 中使用 (!!!) 运算符? [复制]

JavaScript if(x),==和===解析(翻译整理)

在 PHP 中将字符串解析为布尔值

解析为布尔值或检查字符串值

如何在 JavaScript 中将字符串转换为布尔值?