「abcd」.StartsWith(“”)がtrueを返すのはなぜですか?


87

タイトルは質問全体です。誰かが私にこれが起こる理由を教えてもらえますか?

回答:


164

はい-空の文字列で始まるためです。実際、空の文字列は論理的にすべての文字ペアの間に発生します。

このように言えば、これを排除する「で始まる」の定義をどのように与えることができますか?「で始まる」の簡単な定義は次のとおりです。

「xの最初のy.Length文字がyの最初の文字と一致する場合、xはyで始まります。」

代替(同等の)定義:

「xはyで始まりますx.Substring(0, y.Length).Equals(y)


3
x.Substring(0、y.Length).Equals(y)の場合、xはyで始まります。y.Length> 0の場合のみ
Vinko Vrsalovic 2008年

8
うん、あなたは確かにこのケースを明示的に除外することができます。しかし、それはかなりエレガントでない定義ですよね?
ジョンスキート

7
本当。また、それらもnull以外である必要があります...しかし、これらは両方とも、単純な定義の精神を取り除きながら、精度を高めると思います:)
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と同じ長さのこの文字列の先頭にある部分文字列と比較し、それらが等しいかどうかを示す値を返します。等しくするには、値は空の文字列(Empty)、この同じインスタンスへの参照、またはこのインスタンスの先頭と一致する必要があります。

.NET String.StartsWith

引数で表される文字シーケンスが、この文字列で表される文字シーケンスのプレフィックスである場合はtrue。それ以外の場合はfalse。引数が空の文字列であるか、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 stringss は、 t ifs.Length >= t.Lengthとの最初のt.Length文字ts。の文字と一致することから始まります。つまり、s.Length >= t.LengthそしてそのInt32 indexようなすべてについて0 <= index < t.Lengths[index] == t[index]は真実です。逆に、我々はそれが言うsと起動しないtif文

s.Length < t.Lengthまたはs.Length >= t.LengthInt32 indexそのようなものが0 <= index < t.Lengthあり、s[index] != t[index]

本当です。平易な英語でsは、は、より短いtか、そうでない場合は、tの同じ位置として文字と一致しない文字がありsます。

次に、文字列を修正しますss空の文字列で始まることを確立します。s空の文字列で始まらないのは事実ではないことを示すことによってこれを行います。s空の文字列で始まらない場合、s.Length < String.Empty.Lengthまたはs.Length >= String.Empty.LengthInt32 indexそのようなものがあり0 <= index < String.Empty.Lengthます。しかしs.Length >= 0、とString.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.Lengthまたはs.Length >= String.Empty.LengthそしてそのInt32 indexようなものがあります0 <= index < String.Empty.Length

は誤りです。したがって、s空の文字列で始まらない場合はありません。したがって、s空の文字列で開始する必要があります。

以下は、の拡張子としてコード化されたstartsの実装です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;
}

上記の2つの太字の事実は、空虚な真のステートメントの例です。それらを定義するステートメント(サブセット始まり)が空の宇宙に対する全称記号であるという事実のおかげで、それらは真実です。空のセットには要素がないため、他の固定セットにない空のセットの要素はありません。空の文字列には文字がないため、空の文字列の一部の位置が他の固定文字列の同じ位置の文字と一致しないため、文字を含めることはできません。


13

"abcd".StartsWith("")falseを返すとしましょう。

もしそうなら、次の式は真または偽で何を評価しますか?

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

evalsがtrueであることが判明したため、文字列は空の文字列で始まります;-)つまり、位置0で始まり長さが0の「abcd」の部分文字列は空の文字列「」と等しくなります。かなり論理的なイモ。


「abcd」.Substring(0,0)が空の文字列を返すという事実は、「abcd」が実際に空の文字列で始まることを意味するわけではありません。null同様に適切な戻り値であるように、結果は「未定義」と宣言されている可能性もあります。
トム・リント

@TomLintいいえ。通常、条件IE x.FirstName.StartsWith(userEnteredFirstName)&& x.LastName.StartsWith(userEnteredLastName)...を組み合わせます。これにより、入力された値の1つが空の文字列であっても条件が機能します。
ポップカタリン

7

C#では、これは仕様が反応するように指示する方法です。

等しくするには、値は空の文字列(Empty)、この同じインスタンスへの参照、またはこのインスタンスの先頭と一致する必要があります。


5

2つの文字列の最初のN文字は同じです。Nは2番目の文字列の長さ、つまりゼロです。


5

「abcd」.StartsWith(“”)がtrueを返すのはなぜですか?

本当の答え:

そうでなければ、次のような場合があります。

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

    but yet

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

そして、Y2Kが再び発生するのは、それ自体で始まる等しい文字列に依存するすべての銀行ソフトウェアがアカウントを混乱させ、突然ビル・ゲイツが私の富を手に入れ、私が彼を手に入れてしまうからです。運命は私にはそんなに親切ではありません。


同意しません。"" .startsWith( "")はtrueに等しいはずです。これは、文字列が同一であり、奇妙なビジネスロジックが原因ではないためです。
トム・リント

...あなたは答えにassertationと一致することにしてい@TomLint
neonblitzer

4

念のため、次のチェックを明示的に行うString.StartsWith()メソッドSystem.Globalization.CultureInfo.IsPrefix()を内部的に呼び出します。

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

1

文字列は「何もない」で始まるからです。


1
...つまり、string.emptyが何もない場合です!この過度の単純化は一般化できません。より集合論指向の議論に従うことをお勧めします。
Pita.O 2009

1

正規表現で考えると理にかなっています。すべての文字列(「abcd」だけでなく、「」と「sdf \ nff」も)は、「空の文字列で始まる」の正規表現を評価するときにtrueを返します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.