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

JavaScript 有 parseInt()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";
}

这是一个好功能吗?请给我您的反馈。

谢谢!

【问题讨论】:

标签: javascript


【解决方案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 是安全的方式(不确定是否最快)。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-08-22
            • 2011-06-14
            • 2019-02-10
            • 1970-01-01
            相关资源
            最近更新 更多