0

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

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

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

(这里小提琴)

所以我的代码应该做的是失败,如果1)值不是数字并且包含至少一个空格并且在最后一个空格之后有超过2个字符,或者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 时才返回 false,但这里似乎并非如此。

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

4

3 回答 3

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
于 2013-09-09T19:39:31.047 回答
0

这是真实的:

我认为 OR 条件仅在 OR 两边都为 false 时才返回 false

对这个:

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

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

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

于 2013-09-09T19:38:14.583 回答
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')
于 2013-09-09T19:46:11.713 回答