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

时间:2020-03-06 14:50:33  来源:igfitidea点击:

标题是整个问题。有人可以告诉我为什么会发生这种情况吗?

解决方案

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

.NET String.StartsWith

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

Java String.startsWith

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

这样说:我们能给"开始于"的什么定义排除这种情况吗?这是一个简单的"开始于"的定义,它没有:

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

替代(等效)定义:

"如果x.Substring(0,y.Length).Equals(y),则x以y开头"

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

在C语言中,规范是如何告诉它做出反应的;

To be equal, value must be an empty string (Empty), a reference to this same instance, or match the beginning of this instance.

因为字符串以" nothing"开头。

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

我将尽力阐述乔恩·斯凯特(Jon Skeet)所说的话。

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

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

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

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

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

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

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

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

空集是每个集的子集。

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

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

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

首先,我们必须就"始于"的定义达成共识。假设s和t为字符串s假设如果s.Length> = t.Length和t的前t.Length个字符匹配,则s以t开头。的s。也就是说,s.Length> = t.Length,并且对于每个Int32 index',使得0 <= index <t.Lengths [index] == t [index]为真。相反,如果语句如下,我们将说s不是以t`开头

s.Length <t.Length或者s.Length> = t.Length,并且存在一个Int32索引,使得'0 &lt;= index &lt;t.Length和s [index]!= t [索引]

是真的。用简单的英语来说," s"比" t"短,如果不是,则" t"中有一个字符与在" s"中相同位置的字符不匹配。

现在修复字符串" s"。我将确定s以空字符串开头。我将通过显示s'不是以空字符串开头的情况来做到这一点。如果s不是以空字符串开头,则s.Length &lt;String.Empty.Length或者s.Length> = String.Empty.Length,并且有一个Int32索引,使得'0 &lt;= index &lt;String.Empty.Length。但是s.Length> = 0和String.Empty.Length等于零,因此s.Length <String.Empty.Length是不可能的。类似地,由于String.Empty.Length''等于零,因此没有Int32索引可满足0 <= index <String.Empty.Length''。所以

s.Length <String.Empty.Length或者s.Length> = String.Empty.Length并存在一个Int32索引,使得0 <= index <String.Empty.Length`

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

以下是start的实现,其编码为对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;
}

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

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

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