c# - 英語 - 大文字と小文字を区別しない 'Contains(string)'




大文字 小文字 区別しない 英語 (16)

.NET Core 2.0以上のみ(現在)

.NET Coreには、バージョン2.0以降、これに対処するためのメソッドが用意されています。

  • String.Contains(Char、 StringComparison
  • String.Contains(String、 StringComparison

例:

"Test".Contains("test", System.StringComparison.CurrentCultureIgnoreCase);

時間がたつにつれて、おそらく.NET Standardへ、そしてそこからBase Class Libraryの他のすべての実装に移行するでしょう。

次のようなリターンを真にする方法はありますか?

string title = "ASTRINGTOTEST";
title.Contains("string");

私は大文字と小文字の区別を設定することができますオーバーロードされていないようです。現在、私は両方の大文字ですが、それはちょうど愚かです(アップとダウンのケーシングに付属しているi18n問題を参照している)。

更新
この質問は古くからあり、それ以来私は本当に広大で難しい話題について簡単に答えを求めました。
ほとんどの場合、単一言語の英語のコードベースでは、 this回答で十分です。 私はここに来るほとんどの人々がこのカテゴリに入るのでこれが最も一般的な答えだと疑っています。
しかし、 This答えは、両方のテキストが同じ文化であり、その文化が何であるかを知るまで、大文字と小文字を区別しないという固有の問題を引き起こします。 これは多分あまり一般的ではない答えですが、私はそれがより正確であると思うので、私はそのようにマークしました。


RegExを使用することは、これを行うための直接的な方法です。

Regex.IsMatch(title, "string", RegexOptions.IgnoreCase);

StringExtensionクラスは先進的な方法ですが、上の投稿をいくつか組み合わせて完全なコード例を示します:

public static class StringExtensions
{
    /// <summary>
    /// Allows case insensitive checks
    /// </summary>
    public static bool Contains(this string source, string toCheck, StringComparison comp)
    {
        return source.IndexOf(toCheck, comp) >= 0;
    }
}

VisualBasicアセンブリのInStrメソッドは、国際化について懸念がある場合(または再実装できる場合)には最適です。 それを見ると、dotNeetPeekは、大文字と小文字を区別するだけでなく、かな型と半角の文字(大部分はアジア言語に関連しますが、ローマ字の全角バージョンもあります)。 私はいくつかの詳細をスキップしていますが、プライベートメソッドInternalInStrTextチェックアウト:

private static int InternalInStrText(int lStartPos, string sSrc, string sFind)
{
  int num = sSrc == null ? 0 : sSrc.Length;
  if (lStartPos > num || num == 0)
    return -1;
  if (sFind == null || sFind.Length == 0)
    return lStartPos;
  else
    return Utils.GetCultureInfo().CompareInfo.IndexOf(sSrc, sFind, lStartPos, CompareOptions.IgnoreCase | CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth);
}

IndexOf()ように使用できます:

string title = "STRING";

if (title.IndexOf("string", 0, StringComparison.CurrentCultureIgnoreCase) != -1)
{
    // The string exists in the original
}

0(ゼロ)はインデックスである可能性があるため、-1と照合します。

MSDN

その文字列が見つかった場合は0から始まるインデックス値の位置、そうでない場合は-1です。 valueがString.Emptyの場合、戻り値は0です。


string.indexof ()関数を使用することができます。 これは大文字と小文字を区別しません


OrdinalIgnoreCase、CurrentCultureIgnoreCaseまたはInvariantCultureIgnoreCase?

これが欠落しているので、どちらを使用するかに関するいくつかの推奨事項を以下に示します。

Dos

  • 比較には、 StringComparison.OrdinalIgnoreCaseを使用します。これは、カルチャに依存しない文字列のマッチングのための安全なデフォルトです。
  • 高速化のためにStringComparison.OrdinalIgnoreCase比較を使用しStringComparison.OrdinalIgnoreCase
  • 出力をユーザーに表示するときは、 StringComparison.CurrentCulture-based文字列操作StringComparison.CurrentCulture-based使用します。
  • 不変のカルチャに基づいた文字列操作の現在の使用を切り替えて、比較が非言語のStringComparison.OrdinalまたはStringComparison.OrdinalIgnoreCaseを使用するようにする
    言語的に無関係(例えば、象徴的)。
  • 比較のために文字列を正規化するときは、 ToLowerInvariantではなくToUpperInvariant使用します。

しないでください

  • 文字列比較メカニズムを明示的または暗黙的に指定しない文字列操作には、オーバーロードを使用します。
  • StringComparison.InvariantCultureベースの文字列を使用する
    ほとんどの場合、操作。 いくつかの例外のうちの1つは、
    言語的に意味があるが、文化に依存しないデータを持続させる。

これらのルールに基づいて、以下を使用する必要があります。

string title = "STRING";
if (title.IndexOf("string", 0, StringComparison.[YourDecision]) != -1)
{
    // The string exists in the original
}

[YourDecision]は上記の推奨事項に依存します。

ソースのリンク: http://msdn.microsoft.com/en-us/library/ms973919.aspx : http://msdn.microsoft.com/en-us/library/ms973919.aspx


ここのトリックは、大文字と小文字を無視して文字列を検索することですが、大文字と小文字は同じにしておきます。

 var s="Factory Reset";
 var txt="reset";
 int first = s.IndexOf(txt, StringComparison.InvariantCultureIgnoreCase) + txt.Length;
 var subString = s.Substring(first - txt.Length, txt.Length);

出力は「リセット」です


これは他の例と非常によく似ていますが、他の選択肢は通常は必要ないので、ブール値に簡単に列挙することにしました。 ここに私の例があります:

public static class StringExtensions
{
    public static bool Contains(this string source, string toCheck, bool bCaseInsensitive )
    {
        return source.IndexOf(toCheck, bCaseInsensitive ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal) >= 0;
    }
}

使い方は次のようなものです:

if( "main String substring".Contains("SUBSTRING", true) )
....

これらは最も簡単な解決策です。

  1. のインデックス別

    string title = "STRING";
    
    if (title.IndexOf("string", 0, StringComparison.CurrentCultureIgnoreCase) != -1)
    {
        // contains 
    }
    
  2. ケースを変更する

    string title = "STRING";
    
    bool contains = title.ToLower().Contains("string")
    
  3. 正規表現

    Regex.IsMatch(title, "string", RegexOptions.IgnoreCase);
    

ちょうどこのような:

string s="AbcdEf";
if(s.ToLower().Contains("def"))
{
    Console.WriteLine("yes");
}

文字列のparagraphに文字列のwordが含まれているかどうかをテストする(thanks @QuarterMeister)

culture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0

ここで、 cultureは、テキストが書き込まれる言語を記述するCultureInfoのインスタンスです。

このソリューションは、言語に依存する大文字と小文字の区別の定義については透過です。 たとえば、英語では9番目の英字の大文字と小文字にIiを使用しますが、トルコ語では29文字のアルファベットの11番目と12番目の文字にこれらの文字を使用します。 トルコ語の大文字の「i」は、よく知られていない文字「İ」です。

したがって、文字列tinTINは、 英語では同じ単語です、トルコでは異なる単語です。 私が理解するように、1つは「精神」を意味し、もう1つはオノマトペ語です。 (トルコ人、私が間違っている場合は私を修正してください、またはよりよい例を提案してください)

要約すると、テキストがどの言語であるかを知っている場合にのみ、「これらの2つの文字列は同じですが異なるケースで」という質問に答えることができます 。 あなたが知らないなら、あなたはパントを取らなければならないでしょう。 ソフトウェアにおける英語の覇権を考えると、おそらくCultureInfo.InvariantCultureに頼るべきです。なぜなら、それはよく知られている方法で間違っているからです。


最終的には、一般的な「包含」操作がこのような関数になります。

/// <summary>
/// Determines whether the source contains the sequence.
/// </summary>
/// <typeparam name="T">The type of the items in the sequences.</typeparam>
/// <param name="sourceEnumerator">The source enumerator.</param>
/// <param name="sequenceEnumerator">The sequence enumerator.</param>
/// <param name="equalityComparer">An equality comparer.</param>
/// <remarks>
/// An empty sequence will return <c>true</c>.
/// The sequence must support <see cref="IEnumerator.Reset"/>
/// if it does not begin the source.
/// </remarks>
/// <returns>
/// <c>true</c> if the source contains the sequence;
/// otherwise <c>false</c>.
/// </returns>
public static bool Contains<T>(
    IEnumerator<T> sourceEnumerator,
    IEnumerator<T> sequenceEnumerator,
    IEqualityComparer<T> equalityComparer)
{
    if (equalityComparer == null)
    {
        equalityComparer = EqualityComparer<T>.Default;
    }

    while (sequenceEnumerator.MoveNext())
    {
        if (sourceEnumerator.MoveNext())
        {
            if (!equalityComparer.Equals(
                sourceEnumerator.Current,
                sequenceEnumerator.Current))
            {
                sequenceEnumerator.Reset();
            }
        }
        else
        {
            return false;
        }
    }

    return true;
}

これはIEnumerableを受け入れる拡張バージョンで簡単にラップすることができます。

public static bool Contains<T>(
        this IEnumerable<T> source,
        IEnumerable<T> sequence,
        IEqualityComparer<T> equalityComparer = null)
{
    if (sequence == null)
    {
        throw new ArgumentNullException("sequence");
    }

    using(var sequenceEnumerator = sequence.GetEnumerator())
    using(var sourceEnumerator = source.GetEnumerator())
    {
        return Contains(
            sourceEnumerator,
            sequenceEnumerator,
            equalityComparer);
    }
}

これは、文字列を含むシーケンスの順序を比較するために機能しstringIEnumerable<char>実装しているため、

// The optional parameter ensures the generic overload is invoked
// not the string.Contains() implementation.
"testable".Contains("est", EqualityComparer<char>.Default)

しかし、わかっているように、文字列は一般的ではなく、特殊化されています。 プレイには2つの重要な要素があります。

  1. それ自体がさまざまな言語に依存するエッジケースを持つ「ケーシング」問題です。
  2. 「テキスト要素」のセット(文字/数字/記号など)がどのようにUnicodeコードポイントによって表現されるか、与えられた文字列を表すことができる有効な文字列はどのように関係するのか?

正味の効果は同じです。 あなたが主張するかもしれない文字列は、言語的に等しいものは、さまざまな文字の組み合わせで有効に表現できます。 さらに、文化間の妥当性のための規則は変わる。

これにより、このような特殊な文字列ベースの "Contains"実装が実現します。

using System.Globalization;

public static bool Contains(
         this string source,
         string value,
         CultureInfo culture = null,
         CompareOptions options = CompareOptions.None)
{
    if (value == null)
    {
        throw new ArgumentNullException("value");
    }

    var compareInfo = culture == null ? 
            CultureInfo.CurrentCulture.CompareInfo :
            culture.CompareInfo;

    var sourceEnumerator = StringInfo.GetTextElementEnumerator(source);
    var sequenceEnumerator = StringInfo.GetTextElementEnumerator(value);

    while (sequenceEnumerator.MoveNext())
    {
        if (sourceEnumerator.MoveNext())
        {
            if (!(compareInfo.Compare(
                    sourceEnumerator.Current,
                    sequenceEnumerator.Current,
                    options) == 0))
            {
                sequenceEnumerator.Reset();
            }
        }
        else
        {
            return false;
        }
    }

    return true;
}

この関数は、文字列の正規化が何であれ、大文字小文字を区別せず、カルチャ固有の "contains"を実行するのに使用できます。 例えば

"testable".Contains("EST", StringComparer.CurrentCultureIgnoreCase)

渡された文字列が文字列内にあるかどうかを確認するには、単純な方法があります。

string yourStringForCheck= "abc";
string stringInWhichWeCheck= "Test abc abc";

bool isContaines = stringInWhichWeCheck.ToLower().IndexOf(yourStringForCheck.ToLower()) > -1;

This boolean value will return if string contains or not

答えの1つの問題は、文字列がnullの場合に例外がスローされることです。 それをチェックとして追加して、そうしないようにすることができます:

public static bool Contains(this string source, string toCheck, StringComparison comp)
{
    if (string.IsNullOrEmpty(toCheck) || string.IsNullOrEmpty(source))
        return true;

    return source.IndexOf(toCheck, comp) >= 0;
} 

if ("strcmpstring1".IndexOf(Convert.ToString("strcmpstring2"), StringComparison.CurrentCultureIgnoreCase) >= 0){return true;}else{return false;}






case-insensitive