我的程序中有一个变量v
,它可能会从值集中获取任何值
"a", "b", "c", ..., "z"
我的目标是仅在v
不是"x"
,"y"
或"z"
时才执行某些声明。
我试过了,
用于类C语言(其中相等运算符比较实际字符串值;例如。c#,javascript,php)
if (v != "x" || v != "y" || v != "z")
{
// the statements I want to be executed
// if v is neither "x", nor "y", nor "z"
}
用于Pascal类语言(例如plsql)
IF (v != 'x' OR v != 'y' OR v != 'z') THEN
-- the statements I want to be executed
-- if v is neither "x", nor "y", nor "z"
END IF;
if条件中的语句总是被执行。我做错了吗?
答案 0 :(得分:21)
使用&&
/ AND
/ and
,而不是||
/ OR
/ or
:
v != "x" && v != "y" && v != "z"
如果始终执行if
块,则if块的条件始终计算为true
。逻辑表达式必定是错误的。
让我们为v != "x" || v != "y" || v != "z"
的每个值考虑v
。
v = "x"
,
v != "x"
变为"x" != "x"
, false 。
v != "y"
变为"x" != "y"
, true 。
v != "z"
变为"x" != "y"
, true 。
表达式的计算结果为false || true || true
, true 。
当v = "y"
时,表达式变为
"y" != "x" || "y" != "y" || "y" != "z"
或true || false || true
, true 。
当v = "z"
时,表达式变为
"z" != "x" || "z" != "y" || "z" != "z"
或true || true || false
, true 。
对于v
的任何其他值,表达式的计算结果为true || true || true
, true 。
或者,考虑一下真值表:
│ A B C │
v │ v != "x" v != "y" v != "z" │ A || B || C
───────┼──────────────────────────────────┼──────────────
"x" │ false true true │ true
"y" │ true false true │ true
"z" │ true true false │ true
other │ true true true │ true
如您所见,您的逻辑表达式总是评估为true
。
您要做的是,找到一个在
时评估为true
的逻辑表达式
(v is not "x")
的 and
强> (v is not "y")
的 and
强> (v is not "z")
。
正确的结构是,
用于类C语言(例如c#,javascript - (可能需要严格等于运算符!==
),php)
if (v != "x" && v != "y" && v != "z")
{
// the statements I want to be executed
// if v is neither "x", nor "y", nor "z"
}
用于Pascal类语言plsql
IF (v != 'x' AND v != 'y' AND v != 'z') THEN
-- the statements I want to be executed
-- if v is neither "x", nor "y", nor "z"
END IF;
通过De Morgan's law,表达式也可以重写为(使用C语法)
!(v == "x" || v == "y" || v == "z")
含义
<强> not
强> ((v is "x")
的 or
强> (v is "y")
的 or
强> { {1}}。
这使得逻辑更加明显。
某些语言具有用于测试集合中成员资格的特定构造,或者您可以使用数组/列表操作。
sql:(v is "z"))
javascript:v NOT IN ('x', 'y', 'z')
python:["x", "y", "z"].indexOf(v) == -1
答案 1 :(得分:3)
我想我会为Bourne shell脚本提供一个答案,因为语法有点特殊。
在traditional / POSIX sh
中,字符串相等性测试是[
命令的一个特性(是的,这是一个独特的命令名!),它对引用等有一些讨厌的要求。
#### WRONG
if [ "$v" != 'x' ] || [ "$v" != 'y'] || [ "$v" != 'z' ]; then
: some code which should happen when $v is not 'x' or 'y' or 'z'
fi
像Ksh,Bash,Zsh等现代炮弹也有[[
,这有点不太讨厌。
#### STILL WRONG
if [[ $v != 'x' || $v != 'y' || $v != 'z' ]]; then
: some code which should happen when $v is not 'x' or 'y' or 'z'
fi
我们应该强调要求在每个令牌周围留出空格,这是许多初学者忽略的东西(即,在命令和操作符周围没有空格的情况下,你不能说if[[$v
或$v!='y'
),以及明显引用的可选性。未能引用值通常不是语法错误,但如果您未引用需要引用的值,则会导致严重的意外语义问题。 (More on this elsewhere.)
这里明显的解决方法是使用&&
代替||
,但您还应注意[[
通常支持正则表达式,因此您可以说
if [[ ! $v =~ ^(x|y|z)$ ]]; then
: yeah
fi
并且不要忘记可靠的旧case
声明,这对于此非常自然,并且可以移植到20世纪70年代后期:
case $v in
x | y | z)
;; # don't actually do anything in this switch
*) # anything else, we fall through to this switch
yeah
some more yeah
in fact, lots of yeah;;
esac
尾随的双分号最初会引起动脉瘤,但你很快就会恢复,并学会欣赏,甚至爱它们。 POSIX允许你在匹配表达式之前放置一个左括号,这样你就没有不成对的右括号,但这种用法并不常见。
(对于不属于Bourne系列的Unix shell来说,这显然不是一个合适的答案.C系列的shell - 包括仍然有点受欢迎的tcsh
- 使用的语法应该是“C-就像“但这就像无法将Alice Cooper与去仙境的女孩区分开来;鱼壳有其独特的特点,我甚至无法评论。”
答案 2 :(得分:2)
对于PHP,你可以使用类似的东西:
if(strpos('xyz',$v[0])===false)//example 1
//strpos returns false when the letter isn't in the string
//returns the position (0 based) of the substring
//we must use a strict comparison to see if it isn't in the substring
if(!in_array($v[0],array('x','y','z')))//example 2
//example 3
$out=array('x'=>1,'y'=>1,'z'=>1); //create an array
if(!$out[$v[0]]) //check if it's not 1
if(!preg_match('/^[xyz]$/',$v))//example 4, using regex
if(str_replace(array('x','y','z'),'',$v[0]))//example 5
if(trim($v[0],'xyz'))//example 6
对于Javascript:
if(~'xyz'.search(v[0]))//example 1(.indexOf() works too)
if(!(v[0] in {x:0,y:0,z:0}))//example 2
if(~['x','y','z'].indexOf(v[0]))//example 3, incompatible with older browsers.
if(!/^[xyz]$/.match(v))//example 4
if(v.replace(/^[xyz]$/))//example 5
对于MySQL:
Select not locate(@v,'xyz'); -- example 1
select @v not in ('x','y','z'); -- example 2
-- repetition of the same pattern for the others
对于C:
if(!strstr('xyz',v))//example 1, untested
还有更多方法,我太懒了。
运用你的想象力,写下你更喜欢的那个!