【问题标题】:javascript OR (||) not returning expected resultjavascript OR (||) 未返回预期结果
【发布时间】:2013-09-09 19:31:08
【问题描述】:

我有一个字段需要以多种格式接受城市/州的输入值,包括 City ST(伊利诺伊州芝加哥)、City, ST(伊利诺伊州芝加哥)和City,ST(伊利诺伊州芝加哥 - 没有空格之间)。我们正在测试逗号或空格的最后一个实例之后的两个字母的状态代码(因为城市名称可以有空格。)

我有以下代码失败了应该通过的值,反之亦然。

var x = "Chicago,IL";
 if (
 (isNaN(x) && x.indexOf(' ') < 0 && x.split(" ").pop().length > 2) ||
 (isNaN(x) && x.indexOf(',') > 0 && x.split(",").pop().trim().length > 2)
 ) {
     alert("fail");
 }
else {
    alert("pass");
}

(小提琴here

所以我的代码应该做的是失败,如果 1) 值不是数字并且包含至少一个空格并且在最后一个空格之后有超过 2 个字符,或者 2) 值不是数字并且它包含逗号并且逗号后有超过 2 个字符(我正在删除逗号后的潜在空格。)

实际发生的是,它传递了这些值:

Chicago IL
Chicago, IL (with a space, even though it's trimming the space)

但是 Chicago,IL 失败(最初输入时没有空格。)我认为 OR (II) 有问题的原因是,如果我删除第一部分并仅测试包含逗号的值,@ 987654329@ 通过。我认为 OR 条件仅在 OR 两边都为 false 时才返回 false,但这里似乎并非如此。

我敢肯定这是一件非常简单的事情,但我已经盯着它看了太久,根本看不到它。

【问题讨论】:

  • 我认为正则表达式在这里是合适的。
  • 你为什么要在这里执行这个 isNaN 测试?假设您从文本字段中获取值,它应该始终是一个字符串
  • @jackweirdy 但是 isNaN("1") 仍然产生错误。也许她只是想丢弃数字字符串?
  • x.indexOf(' ') &lt; 0 &amp;&amp; x.split(" ").pop().length &gt; 2 没有意义。如果字符串中有空格,则x.indexOf(' ') &lt; 0false,第二个表达式将不会被执行。如果没有空格,x.split(" ") 将返回一个包含一个元素的数组,x 本身。你的意思是x.indexOf(' ') &gt; 0吗?
  • @LexLythius - 是的,我们正在处理不同块中的数字字符串,因为用户可以输入邮政编码或城市/州。只有当它是一个城市/州时,我们才想运行这组测试。

标签: javascript conditional-statements


【解决方案1】:

这似乎太复杂了。如果你打算这样做,使用多个语句(这样可以更容易地推断它们)。无论如何,这是我的“解决方案”,诚然,它并没有试图解决为什么原来没有按预期工作:

var cityState = /^\w+(?:,\s*|\s+)\w{2}$/;
if (cityState.test(input)) {
    // good
}

要接受“City Name, State”或“City Name State”,请考虑这个(更复杂的)正则表达式。这项工作的关键是惰性修饰符和锚定。

function isValidState (st) {
  // This could be turned into an appropriate whitelist, and may include
  // things like "Illinois". 
  return st.length == 2;
}

function parseCityState (cs) {
  var match = cs.match(/^\s*(\w.*?)\s*([, ])\s*(\w+)\s*$/) || [];
  var city = match[1];
  var commaUsed = match[2] == ',';
  var state = match[3];
  if (city && state && isValidState(state)) {
    return {city: city, state: state, commaUse: commaUsed}
  } else {
    return undefined;
  }
}

现在,如果您对原版失败的原因感兴趣,请考虑对“伊利诺伊州芝加哥”为何失败的最新分析。让x = "Chicago, IL",那么:

isNaN(x)       -> true
x.indexOf(' ') -> >0
x.indexOf(',') -> >0
x.split(' ')   -> ["Chicago,", "IL"]
x.split(',')   -> ["Chicago", " IL"]

并替换:

true && (>0 < 0) && ["Chicago,", "IL"].pop().length > 2
||
true && (>0 > 0) && ["Chicago", " IL"].pop().trim().length > 2

再次评估(请注意,“无空格”的测试在第一个表达式行失败,因为有 个空格):

true && false && "IL".length > 2
||
true && true && "IL".length > 2

然后再次评估(请注意,两个表达式行都失败了,因为“IL”的长度仅为 2):

true && false && false
||
true && true && false

最终这会拒绝输入:

false || false -> false

【讨论】:

  • 我同意你的观点,这里的方法是 RegExps,但我认为 OP 要求一些关于 JS 逻辑的更重要的东西。
  • 感谢您的解释。我想使用您的正则表达式,但它不考虑城市名称中可能存在的空格。例如,伊利诺伊州芝加哥通过,但伊利诺伊州芝加哥高地没有。如果有逗号也不起作用(伊利诺伊州芝加哥高地失败。)jsfiddle.net/edzYt/1
  • @user2246674 - 我无法选择我们如何做到这一点;客户提供了非常具体的处理状态和邮政编码的方法。
  • @EmmyS 我已经用一个使用正则表达式但可以处理所描述的更复杂情况的示例更新了代码。如果需要处理更多规则(为了不使正则表达式不可读),根据输入的启发式方法创建一个调用正确“解析器”的调度函数可能会很有用。作为一个原始示例,isNaN 检查可以是调度程序的一部分——我们处理的是邮政编码还是看起来像城市/州字符串的东西?祝你好运!
【解决方案2】:

这是真的:

我认为 OR 条件只有在双方的情况下才会返回 false 或者是假的

关于这个:

如果我删除第一部分并仅测试包含逗号的值,Chicago,IL 通过

在您的提琴手示例中,注释掉第一个测试打印“失败”,这意味着它正在评估为 true

JS OR 没有问题。但你期待的是什么?

【讨论】:

    【解决方案3】:

    我认为你在这行有错误
    x.indexOf(' ') &lt; 0
    应该是
    x.indexOf(' ') &gt; 0


    但如果我是你,我会使用正则表达式:

    var info = 'South Beach, FL';
    var regex = /\w+(\w+ \w+)*\s*,\s*[a-zA-Z]{2}/;
    
    alert(regex.test(info) ? 'Valid' : 'Invalid')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-09
      • 2010-09-22
      • 2021-05-17
      • 2018-02-19
      • 2018-03-23
      • 2020-03-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多