与空字符串一起使用时,InStr返回1

时间:2015-09-07 12:50:41

标签: vb6

我正在努力将一些旧的VB6代码迁移到C#,我一直在针对VB代码测试我的C#代码,以检查每种语言中的对应方法是否返回相同的值。 / p>

我对此if语句有疑问:

If InStr(1, "LPTVJY", strTempTaxCode) <> 0 Then
  strTempTaxCode = "0" & strTempTaxCode
End if

strTtempTaxCode = ""1电话返回InStr(1, "LPTVJY", strTempTaxCode)的值。为什么是这样?据我所知,我应该返回0,因为"LPTVJY"中的所有字符都不在strTempTaxCode

3 个答案:

答案 0 :(得分:1)

非零长度的所有字符串,包括单字符字符串,都包含空字符串。

Debug.Print InStr("abc", "")     ' => 1
Debug.Print InStr("a", "")       ' => 1
Debug.Print "abc" & "" = "abc"   ' => True

如果您无法理解概念,请考虑所有数字都是1:

' (not a real function)
Debug.Print Factors(2)           ' => 1, 2
Debug.Print 2 * 1 = 2            ' => True

这称为 Multiplicative Identity Property 。您可以将字符串视为具有涉及空字符串的类似标识属性。

如果您不希望InStr()匹配空字符串,请在调用之前进行初步测试:

If Len(strTempTaxCode) > 0 Then
    If InStr(1, "LPTVJY", strTempTaxCode) <> 0 Then
      strTempTaxCode = "0" & strTempTaxCode
    End If
End If

答案 1 :(得分:0)

在VB中,字符串是基于1的。因此,当省略时, start 的默认值(要搜索的起始位置)为1.

string2 (你搜索的那个)长度为零或没有时,InStr返回 start * 1),这是你的案例1。

* 1) MSDN documentation on InStr

短语,因为"LPTVJY"中的所有字符都不在strTempTaxCode 中,这表示您误解了该功能。它在string1中搜索string2。文档提到了很多边缘情况以及该情况下函数返回的内容。但是,该函数可能比这简单得多,可以写成嵌套循环,大致如下(只在内部进行了更优化)。

For s = start to Len(string1) - start
  For c = 1 to Len(string2)

    ' Out of characters. There is no match.
    If c+s-1 > Len(string1) then Return 0

    ' Mismatch. Try again for the next value of 's'.
    If SubStr(string1, c+s-1) <> SubStr(string2, c) then Exit For

  Next
Next

' If you get here, a match is found at position s.
Return s

请将上面的代码视为伪代码。它只是为了解释,我不知道它是否真的有效。

答案 2 :(得分:0)

之所以会这样,是因为根据Microsoft documentation,如果要搜索的字符串(即strTempTaxCode)的长度为零,则该函数的返回值为可选的start参数(即开始搜索的索引,在这种情况下将省略)。省略时,其值 NOT 不一定为1,但要搜索的字符串中的第一个字符位置(恰好为1,作为{中的第一个字符位置{1}}顺便说一句。

不会会发生这种情况是因为所有非零长度的字符串(包括单字符字符串)都包含空字符串或以下事实:正如其他人所指出的那样,"LPTVJY"参数为1 ,因为它们不是,不是。要测试此效果,请尝试运行:

start

不幸的是,如果第二个字符串不为空(这将引发错误5:“无效的过程调用或参数”),则此方法将不起作用,但足以证明在以下情况下函数的返回值:要搜索的零长度字符串与它们包含在要搜索的字符串中,或​​者Debug.Print InStr(2, "abc", "") ' Returns 2, i.e. the start position Debug.Print InStr(-13, "abc", "") ' Returns -13, i.e. the start position Debug.Print InStr(-1, "abc", "") ' Returns -1, i.e. the start position Debug.Print InStr(0, "abc", "") ' Returns 0, i.e. the start position Debug.Print InStr(2, "", "") ' Returns 0, i.e. the first character position in "" 的值默认为1无关,而是与结果为 every 无关。 em> start参数的值是(即使在最后一个测试用例中,由于要搜索的空字符串中的第一个字符位置也是0,因此它也被强制为0)。

最快的解决方案可以是:

•对于start语句,请使用附加条件,例如指出的Bond

if..then..else

•对于分配语句,创建一个UDF(用户定义函数)来处理它:

If Len(strTempTaxCode) > 0 And InStr(1, "LPTVJY", strTempTaxCode) > 0 Then
  strTempTaxCode = "0" & strTempTaxCode
End if`

其他提出的解决方案速度较慢。上面这两个中的第一个在0.03 s内运行了100万次,与单条件Public Function InString(Optional startposition As Long = 1, Optional searchinto As String = "", Optional searchfor As String = "", Optional comparisonmethod As VbCompareMethod = vbBinaryCompare) As Long If Len(searchfor) < 1 Then InString = -1 Else InString = InStr(startposition, searchinto, searchfor, comparisonmethod) End Function 相同,而第二个在0.30 s内运行。如您所见,仅因为Microsoft认为即使明显InStr包含在start之类的字符串中,"",它仍应返回"LPTVJY"值,用户有时必须使用比原始功能慢10倍的UDF。有趣的是,就像谎言在重复多次后变成真相一样,有些人甚至认为这是应该的,因为那是它的实现方式。