经典 ASP InStr() 在空比较字符串上计算 True

Classic ASP InStr() Evaluates True on Empty Comparison String

我 运行 遇到了经典 ASP VbScript InStr() 函数的问题。如下图,第二次调用InStr() returns 1 在非空字符串中查找空字符串时。我很好奇为什么会这样。

' InStr Test
Dim someText : someText = "So say we all"
Dim emptyString : emptyString = ""

'' I expect this to be true
If inStr(1,someText,"so",1) > 0 Then
    Response.write ( "I found ""so""<br />" )
End If 

'' I expect this to be false
If inStr(1, someText, emptyString, 1) > 0 Then
    Response.Write( "I found an empty string<br />" )
End If

编辑: 一些额外的说明:在调试遗留代码时出现问题的原因 运行 进入这样的情况:

Function Go(value)
     If InStr(1, "Option1|Option2|Option3", value, 1) > 0 Then
          ' Do some stuff
     End If
End Function

在某些情况下,可以使用空字符串调用函数 Go()。最初开发人员的意图不是检查 value 是否为空,而是检查 value 是否等于管道分隔值(Option1、Option2 等)之一。

进一步考虑,每个字符串都是从空字符串创建的,这是有道理的,我可以理解为什么编程语言会假定删除所有字符后的字符串仍然包含空字符串。

我不明白为什么编程语言要实现这个。考虑这两个语句:

InStr("so say we all", "s") '' evaluates to 1
InStr("so say we all", "")  '' evaluates to 1

InStr() 函数将 return 一个字符串在另一个字符串中第一次出现的位置。以上两种情况,结果都是1。但是,位置1总是包含字符"s",而不是空字符串。此外,单独对空字符串使用另一个字符串函数(如 Len() 或 LenB())将导致 0,表示字符长度为 0。

这里好像有些不一致。所有字符串中包含的空字符串实际上不是一个字符,但 InStr() 函数将其视为一个字符,而其他字符串函数则不是。我发现这是不直观和不必要的。

恕我直言,这是正确的。至少我希望空字符串是任何其他字符串的一部分。但也许这是一个哲学问题。 ASP 这样做,所以接受它。实际上,如果您需要不同的行为,请编写自己的方法、InStrNotEmpty 或其他东西,returns 在空搜索字符串上为 false。

我很困惑为什么你认为这种行为是不正确的。如果问 Does 'abc' contain ''? 甚至有意义,答案必须是 "yes": All strings contain the empty string as a trivial case .所以你 "why is this happening" 问题的答案是因为这是唯一明智的做法。

字符串的Empty String is the Identity Element

The identity element I (also denoted E, e, or 1) of a group or related mathematical structure S is the unique element such that Ia=aI=a for every element a in S. The symbol "E" derives from the German word for unity, "Einheit." An identity element is also called a unit element.

如果你给一个数字n加0,结果就是n;如果你 add/concatenate "" 到一个字符串 s 结果是 s:

>> WScript.Echo CStr(1 = 1 + 0)
>> WScript.Echo CStr("a" = "a" & "")
>>
True
True

所以每个String和SubString至少包含一个"":

>> s = "abc"
>> For p = 1 To Len(s)
>>     WScript.Echo InStr(p, s, "")
>> Next
>>
1
2
3

Instr() 忠实地报告了这一点。文档甚至声明:

InStr([start, ]string1, string2[, compare])
...
The InStr function returns the following values:
...
string2 is zero-length            start

WRT 你的

However, position 1 always contains the character "s", not an empty string.

==>

Position 1 always contains the character "s", and therefore an empty string too.