[C#] केस असंवेदनशील 'शामिल है (स्ट्रिंग)'


Answers

आप String.IndexOf विधि का उपयोग कर सकते हैं और स्ट्रिंग कॉम्परिसन पास कर सकते हैं। ऑर्डिनल इग्नोरकेस का उपयोग करने के लिए खोज के प्रकार के रूप में:

string title = "STRING";
bool contains = title.IndexOf("string", StringComparison.OrdinalIgnoreCase) >= 0;

स्ट्रिंग के लिए एक नई एक्सटेंशन विधि को भी परिभाषित करना बेहतर है:

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

नोट, वह शून्य प्रचार ?. पुराने संस्करणों के उपयोग के लिए सी # 6.0 (वीएस 2015) के बाद उपलब्ध है

   if(source==null) return false;
   return source.IndexOf(toCheck, comp) >= 0;

उपयोग:

string title = "STRING";
bool contains = title.Contains("string", StringComparison.OrdinalIgnoreCase);
Question

क्या निम्नलिखित वापसी सही करने का कोई तरीका है?

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

ऐसा लगता है कि एक अधिभार नहीं है जो मुझे केस संवेदनशीलता सेट करने की अनुमति देता है .. वर्तमान में मैं दोनों को अपरिपक्व करता हूं, लेकिन यह सिर्फ मूर्खतापूर्ण है।

अद्यतन करें
मैं जिस मूर्खता का उल्लेख करता हूं वह i18n समस्या है जो ऊपर और नीचे आवरण के साथ आती है।

अद्यतन करें
यह सवाल प्राचीन है और तब से मुझे एहसास हुआ है कि मैंने वास्तव में विशाल और कठिन विषय के लिए एक सरल उत्तर मांगा है, यदि आप इसकी पूरी तरह जांच कर रहे हैं।
ज्यादातर मामलों के लिए, मोनो-भाषाई में, अंग्रेजी कोड आधार this उत्तर पर्याप्त होगा। मुझे संदेह है क्योंकि यहां आने वाले ज्यादातर लोग इस श्रेणी में आते हैं यह सबसे लोकप्रिय उत्तर है।
This उत्तर हालांकि अंतर्निहित समस्या को सामने लाता है कि हम टेक्स्ट केस असंवेदनशील की तुलना नहीं कर सकते हैं जब तक हम जानते हैं कि दोनों ग्रंथ समान संस्कृति हैं और हम जानते हैं कि वह संस्कृति क्या है। यह शायद एक कम लोकप्रिय उत्तर है, लेकिन मुझे लगता है कि यह अधिक सही है और इसलिए मैंने इसे इस तरह चिह्नित किया।




यह यहां अन्य उदाहरण के समान है, लेकिन मैंने बूल को प्राथमिक बनाने के लिए enum को सरल बनाने का निर्णय लिया है, प्राथमिक क्योंकि अन्य विकल्पों की सामान्य रूप से आवश्यकता नहीं होती है। मेरा उदाहरण यहां दिया गया है:

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) )
....



सिर्फ इस तरह:

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



आखिरकार, एक सामान्य "शामिल" ऑपरेशन इस तरह के एक समारोह में आता है,

/// <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;
}

इसे एक विस्तार संस्करण में छोटा रूप से लपेटा जा सकता है जो इस तरह की संख्या को स्वीकार करता है,

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);
    }
}

अब, स्ट्रिंग समेत किसी भी अनुक्रम की क्रमिक तुलना के लिए यह काम करेगा, क्योंकि string लागू करता है IEnumerable<char> ,

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

हालांकि, जैसा कि हम जानते हैं, तार सामान्य नहीं हैं, वे विशिष्ट हैं। खेल में दो महत्वपूर्ण कारक हैं।

  1. "आवरण" मुद्दा जिसमें स्वयं के विभिन्न भाषा निर्भर किनारे हैं।
  2. यूनिकोड कोड पॉइंट्स द्वारा वर्णित "टेक्स्ट एलिमेंट्स" (अक्षरों / संख्याओं / प्रतीकों इत्यादि) का एक सेट किस प्रकार शामिल किया गया है और वर्णों के वैध अनुक्रम एक दिए गए स्ट्रिंग का प्रतिनिधित्व कर सकते हैं, these answers में विवरण विस्तृत किए गए हैं।

शुद्ध प्रभाव वही है। स्ट्रिंग्स जो आप जोर दे सकते हैं भाषाई रूप से बराबर हैं, वर्णों के विभिन्न संयोजनों द्वारा वैध रूप से प्रतिनिधित्व किया जा सकता है। और भी, संस्कृतियों के बीच वैधता के नियम बदल जाते हैं।

यह सब इस तरह के एक विशेष स्ट्रिंग आधारित "युक्त" कार्यान्वयन की ओर जाता है।

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;
}

इस फ़ंक्शन का उपयोग केस असंवेदनशील, संस्कृति विशिष्ट "युक्त" करने के लिए किया जा सकता है जो काम करेगा, स्ट्रिंग के सामान्यीकरण जो भी हो। जैसे

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



आप string.indexof () फ़ंक्शन का उपयोग कर सकते हैं। यह मामला असंवेदनशील होगा




Regex का उपयोग कर वैकल्पिक समाधान:

bool contains = Regex.IsMatch("StRiNG to search", "string", RegexOptions.IgnoreCase);

नोटिस

जैसा कि @ सीएचओओ ने अपनी टिप्पणी में बताया है, वहां परिदृश्य हैं जो इस समाधान को गलत नतीजे वापस करने का कारण बनेंगे। सुनिश्चित करें कि आप इस समाधान को खतरनाक रूप से लागू करने से पहले क्या कर रहे हैं, यह सुनिश्चित करें।




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);
}



उत्तर के साथ एक मुद्दा यह है कि यदि स्ट्रिंग शून्य है तो यह अपवाद फेंक देगा। आप इसे एक चेक के रूप में जोड़ सकते हैं, इसलिए यह नहीं होगा:

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;
} 



नौसिखिया के लिए सरल तरीका:

title.ToLower().Contains("string");//of course "string" is lowercase.



public static class StringExtension
{
    #region Public Methods

    public static bool ExContains(this string fullText, string value)
    {
        return ExIndexOf(fullText, value) > -1;
    }

    public static bool ExEquals(this string text, string textToCompare)
    {
        return text.Equals(textToCompare, StringComparison.OrdinalIgnoreCase);
    }

    public static bool ExHasAllEquals(this string text, params string[] textArgs)
    {
        for (int index = 0; index < textArgs.Length; index++)
            if (ExEquals(text, textArgs[index]) == false) return false;
        return true;
    }

    public static bool ExHasEquals(this string text, params string[] textArgs)
    {
        for (int index = 0; index < textArgs.Length; index++)
            if (ExEquals(text, textArgs[index])) return true;
        return false;
    }

    public static bool ExHasNoEquals(this string text, params string[] textArgs)
    {
        return ExHasEquals(text, textArgs) == false;
    }

    public static bool ExHasNotAllEquals(this string text, params string[] textArgs)
    {
        for (int index = 0; index < textArgs.Length; index++)
            if (ExEquals(text, textArgs[index])) return false;
        return true;
    }

    /// <summary>
    /// Reports the zero-based index of the first occurrence of the specified string
    /// in the current System.String object using StringComparison.InvariantCultureIgnoreCase.
    /// A parameter specifies the type of search to use for the specified string.
    /// </summary>
    /// <param name="fullText">
    /// The string to search inside.
    /// </param>
    /// <param name="value">
    /// The string to seek.
    /// </param>
    /// <returns>
    /// The index position of the value parameter if that string is found, or -1 if it
    /// is not. If value is System.String.Empty, the return value is 0.
    /// </returns>
    /// <exception cref="ArgumentNullException">
    /// fullText or value is null.
    /// </exception>
    public static int ExIndexOf(this string fullText, string value)
    {
        return fullText.IndexOf(value, StringComparison.OrdinalIgnoreCase);
    }

    public static bool ExNotEquals(this string text, string textToCompare)
    {
        return ExEquals(text, textToCompare) == false;
    }

    #endregion Public Methods
}



यह साफ और सरल है।

Regex.IsMatch(file,fileNamestr,RegexOptions.IgnoreCase)



Links