我有一个字段需要接受多种格式的城市/州的输入值,包括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,但这似乎不是这种情况。
我确信这是一件非常简单的事,但我一直盯着它看的时间太长而且看不到它。
答案 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')