为什么“ abcd” .StartsWith(“”)返回true?


87

标题是整个问题。有人可以告诉我为什么会这样吗?

Answers:


164

是的-因为它确实以空字符串开头。实际上,空字符串在逻辑上在每对字符之间出现。

这么说:您能给“开始于”的什么定义排除这种情况?这是“开始于”的简单定义,它没有:

“如果x的前y.Length几个字符与y的第一个字符匹配,则x以y开头。”

替代(等效)定义:

“如果x.Substring(0, y.Length).Equals(y)“ x以y开头”


3
如果x.Substring(0,y.Length)。等于且仅当y.Length> 0时,x以y开头
Vinko Vrsalovic

8
是的,您确实可以明确排除这种情况。但是,这是一个非常微不足道的定义,不是吗?
乔恩·斯基特

7
真正。它还要求它们也不能为空...但是我要说的是,这两者都增加了准确性,同时又脱离了简单定义的精神:)
Jon Skeet

8
空字符串的无限次出现在每对字符之间。
Lotus Notes

3
是的,就像在数字前加零-它不会改变值,但它仍然存在。
pop850 2010年

47

我将尽力阐述乔恩·斯基特所说的话。

假设x,y和z是字符串,而+运算符实际上是串联的,那么:

如果我们可以将z拆分为z = x + y,则意味着z以x开头。因为每个字符串z都可以拆分为z =“” + z,所以每个字符串都以“”开头。

因此,因为(“” +“ abcd”)==“ abcd”,所以“ abcd”以“”开头


17

此方法将value参数与该字符串开头的子字符串进行比较,该字符串的长度与value相同,并返回一个值,该值指示它们是否相等。为了相等,value必须是一个空字符串(Empty),对该相同实例的引用或与该实例的开头匹配。

.NET String.StartsWith

如果参数表示的字符序列是此字符串表示的字符序列的前缀,则为true;否则为true。否则为假。还要注意,如果参数为空字符串或等于由equals(Object)方法确定的String对象,则将返回true

Java String.startsWith


17

我将从一个易于理解的相关事实开始。

空集是每个集的子集。

为什么?该定义子集指出A的一个子集B,如果每一个元素A是一个元素B。相反,如果不是的元素,A则不是的子集。BAB

现在修复一个集合B。我将确定空集是的子集B。我将通过显示空集不是的子集来实现这一点B。如果空集不是的子集,B那么我可以找到不在中的空集的元素B。但是空集没有任何元素,因此我找不到不在中的元素B。因此,并非不是空集不是的子集B。因此,空集必须是的子集B

任何字符串都以空字符串开头。

首先,我们必须同意以开头的定义。Let sand tbe strings我们说它s tifs.Length >= t.Length和匹配的第一个t.Length字符开头。也就是说,对于所有这样的情况,都是正确的。相反,我们会说,不启动如果语句tss.Length >= t.LengthInt32 index0 <= index < t.Lengths[index] == t[index]st

s.Length < t.Lengths.Length >= t.Length与有一个Int32 index使得0 <= index < t.Lengths[index] != t[index]

是真的。简而言之,s它比短t,或者如果不短,则存在一个字符,t该字符与中的相同位置不匹配s

现在修复一个字符串s。我将以s空字符串开头。我将通过显示不是s不是以空字符串开头的情况来做到这一点。如果s不是以空字符串开头,则s.Length < String.Empty.Lengths.Length >= String.Empty.Length且有一个Int32 index这样的0 <= index < String.Empty.Length。但是s.Length >= 0String.Empty.Length等于零,因此不可能为s.Length < String.Empty.Length真。类似地,由于``String.Empty.Length is equal to zero, there is noInt32 index satisfying0 <= index <String.Empty.Length`。因此

s.Length < String.Empty.Lengths.Length >= String.Empty.LengthInt32 index这样一个0 <= index < String.Empty.Length

是假的。因此,不是s不是以空字符串开头的情况。因此,s必须以空字符串开头。

以下是开始的实现,编码为的扩展string

public static bool DoStartsWith(this string s, string t) {
    if (s.Length >= t.Length) {
        for (int index = 0; index < t.Length; index++) {
            if (s[index] != t[index]) {
                return false;
            }
        }
        return true;
    }
    return false;
}

以上两个大胆的事实是虚假陈述的例子。由于定义它们(子集以开头)的语句是对空宇宙的通用量化,因此它们是正确的。空集中没有元素,因此空集中没有任何其他固定集中的元素。空字符串中没有字符,因此不能有字符,因为空字符串中的某些位置与其他固定字符串中相同位置的字符不匹配。


13

我们只说"abcd".StartsWith("")return false。

如果是这样,那么以下表达式的含义是正确还是错误:

 ("abcd".Substring(0,0) == "")

结果表明evals为true,因此该字符串确实以空字符串;-)开头,或者换句话说,“ abcd”的子字符串从位置0开始,长度为0等于空字符串“”。十分合逻辑的imo。


“ abcd” .Substring(0,0)返回空字符串的事实并不意味着“ abcd”实际上以空字符串开头。结果也可能已经声明为“未定义”,因为null返回值也同样合适。
汤姆·林特

@TomLint否。通常会组合条件IE x.FirstName.StartsWith(userEnteredFirstName)&& x.LastName.StartsWith(userEnteredLastName)...。即使输入的值之一为空字符串,这也使条件起作用。
Pop Catalin

7

在C#中,这就是规范告诉它如何反应的方式。

为了相等,value必须是一个空字符串(Empty),对该相同实例的引用或与该实例的开头匹配。


5

两个字符串的前N个字符相同。N是第二个字符串的长度,即零。


5

为什么“ abcd” .StartsWith(“”)返回true?

真正的答案:

一定是那样,否则你会遇到这样的情况

    "".startsWith("") == false 
    "".equals("") == true

    but yet

    "a".startsWith("a") == true
    "a".equals("a") == true

然后我们又要重新开始Y2K了,因为所有依赖以相等的字符串开头的银行软件都将使我们的账户混在一起,突然比尔·盖茨就会拥有我的财富,而我会拥有他的财产,该死的!命运对我而言不是那样。


我不同意。“” .startsWith(“”)应该等于true,因为字符串是相同的,而不是因为某些奇怪的业务逻辑。
汤姆·林特

@TomLint您实际上同意答案中的主张...
neonblitzer

4

仅作记录,在String.StartsWith()内部调用该方法System.Globalization.CultureInfo.IsPrefix(),以明确进行以下检查:

if (prefix.Length == 0)
{
    return true;
}

1

因为字符串以“ nothing”开头。


1
...就是string.empty什么都没有!这种过度简化不能一概而论。我建议我们遵循更多面向理论的讨论。
Pita.O

1

如果您以正则表达式的方式来考虑它,那是有道理的。在评估“从空字符串开始”的正则表达式时,每个字符串(不仅是“ abcd”,还有“”和“ sdf \ nff”)都返回true。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.