javascript OR(||)没有返回预期的结果

时间:2013-09-09 19:31:08

标签: javascript conditional-statements

我有一个字段需要接受多种格式的城市/州的输入值,包括City ST(芝加哥IL),City, ST(芝加哥,IL)和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)该值不是数字并且它包含,那么我的代码应该做的是失败一个逗号,逗号后面有两个以上的字符(我在逗号后面修改了一个空格。)

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

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

但失败Chicago,IL(最初没有空格进入。)我认为OR(II)的问题是因为如果我删除第一部分并仅测试包含的值一个逗号,Chicago,IL通过。我认为如果OR的两边都是假的,OR条件只会返回false,但这似乎不是这种情况。

我确信这是一件非常简单的事,但我一直盯着它看的时间太长而且看不到它。

3 个答案:

答案 0 :(得分:1)

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

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

要接受“城市名称,州名”或“城市名称状态”,请考虑这个(更复杂的)正则表达式。这项工作的关键是延迟修饰符和锚定。

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;
  }
}

现在,如果您对原始版本失败的原因感兴趣,请考虑更新分析“Chicago,IL”失败的原因。设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

答案 1 :(得分:0)

这是真的:

  

我认为OR条件只有在两边都返回false   或者是假的

关于这个:

  

如果我删除第一部分并仅测试包含逗号的值,芝加哥,IL传递

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

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

答案 2 :(得分:0)

我认为你在这条线上犯了一个错误 x.indexOf(' ') < 0
应该是 x.indexOf(' ') > 0


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

var info = 'South Beach, FL';
var regex = /\w+(\w+ \w+)*\s*,\s*[a-zA-Z]{2}/;

alert(regex.test(info) ? 'Valid' : 'Invalid')