c# - حالة غير حساسة "يحتوي على (سلسلة)"


هل هناك طريقة لجعل العودة التالية صحيحة؟

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

هناك لا يبدو أن يكون الزائد الذي يسمح لي لضبط حساسية القضية .. حاليا أنا أحسن لهم على حد سواء، ولكن هذا مجرد سخيفة.

تحديث
السخرية التي أشير إليها هي القضايا i18n التي تأتي مع غلاف صعودا وهبوطا.

تحديث
هذا السؤال قديم ومنذ ذلك الحين أدركت أنني سألت عن إجابة بسيطة لموضوع شاسع حقا وصعبة إذا كنت تهتم للتحقيق في ذلك تماما.
بالنسبة لمعظم الحالات، في أحادية اللغة، قواعد اللغة الإنجليزية قواعد هذه الإجابة سوف تكفي. أنا أشك في أن معظم الناس يأتون إلى هنا في هذه الفئة هذا هو الجواب الأكثر شعبية.
إلا أن هذه الإجابة تثير المشكلة الكامنة التي لا يمكننا مقارنتها بحالة النص غير حساسة حتى نعرف أن كلا النصين هما نفس الثقافة ونعرف ما هي تلك الثقافة. هذا ربما إجابة أقل شعبية، ولكن أعتقد أنه هو أكثر صحة وهذا هو السبب في أنني وضعت عليه على هذا النحو.



Answers



لاختبار ما إذا كانت paragraph سلسلة تحتوي على word سلسلة (شكراQuarterMeister)

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

حيث culture هي مثيل CultureInfo تصف اللغة التي يتم كتابة النص فيها.

هذا الحل شفاف حول تعريف حالة عدم الحساسية، والتي تعتمد على اللغة . على سبيل المثال، تستخدم اللغة الإنجليزية الحرفين I و i للإصدارات العلوية والسفلية من الحرف التاسع، في حين أن اللغة التركية تستخدم هذه الأحرف للرسائل الحادية عشرة والثانية عشرة من الأبجدية التي يبلغ طولها 29 حرفا. النسخة التركية العليا حالة 'ط' هو الطابع غير مألوف 'İ'.

وبالتالي فإن tin و TIN هي نفس الكلمة في اللغة الإنجليزية ، ولكن كلمات مختلفة باللغة التركية . كما أفهم، وسيلة واحدة "روح" والآخر هو كلمة أونوماتوبويا. (الأتراك، يرجى تصحيح لي إذا كنت مخطئا، أو اقتراح مثال أفضل)

لتلخيص، يمكنك الإجابة فقط على السؤال "هل هاتين السلاسل نفسه ولكن في حالات مختلفة" إذا كنت تعرف ما هي اللغة النص في . إذا كنت لا تعرف، سيكون لديك لاتخاذ بونت. نظرا للهيمنة الإنجليزية في البرمجيات، يجب عليك على الأرجح اللجوء إلى CultureInfo.InvariantCulture ، لأنها سوف تكون خاطئة بطرق مألوفة.




يمكنك استخدام الأسلوب StringComparison.OrdinalIgnoreCase وتمرير StringComparison.OrdinalIgnoreCase كنوع البحث المطلوب استخدامه:

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

...

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



يمكنك استخدام IndexOf() كما يلي:

string title = "STRING";

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

منذ 0 (صفر) يمكن أن يكون فهرس، تحقق ضد -1.

MSDN

يتم تحديد موضع القيمة الصفري للقيمة إذا تم العثور على هذه السلسلة، أو -1 إذا لم يكن. إذا كانت القيمة String.Empty، قيمة الإرجاع هي 0.




حل بديل باستخدام ريجكس:

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

تنويه

وكما أشارCHao في تعليقه، هناك سيناريو من شأنها أن تتسبب في هذا الحل للعودة نتائج غير صحيحة. تأكد من أنك تعرف ما تفعله قبل تنفيذ هذا الحل عشوائيا.




هل يمكن دائما مجرد أعلى أو أسفل سلاسل أولا.

string title = "string":
title.ToUpper().Contains("STRING")  // returns true

عفوا، رأيت فقط أن بت الماضي. إذا كانت الحالة غير حساسة مقارنة * ربما * تفعل الشيء نفسه على أي حال، وإذا كان الأداء ليست قضية، وأنا لا أرى مشكلة مع إنشاء نسخ كبيرة ومقارنة تلك. يمكن أن أقسم اليمين التي رأيت مرة واحدة حالة غير حساسة مقارنة مرة واحدة ...




قضية واحدة مع الإجابة هي أنه سيتم رمي استثناء إذا كانت سلسلة فارغة. يمكنك إضافة ذلك كشيك بحيث لن:

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



سترينجكستنسيون الفئة هي الطريق إلى الأمام، لقد جمعت اثنين من الوظائف أعلاه لإعطاء مثال شفرة الكامل:

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



هذا هو نظيفة وبسيطة.

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



أوردينالينوريكاس، كيرنتكولتوريونوريكاس أو إنفاريانتكولتورنوريكيس؟

وبما أن هذا مفقود، فإليك بعض التوصيات حول وقت استخدام أي منها:

دوس

  • استخدم StringComparison.OrdinalIgnoreCase للمقارنات كقيمة افتراضية آمنة لمطابقة سلسلة StringComparison.OrdinalIgnoreCase الثقافية.
  • استخدم المقارنات StringComparison.OrdinalIgnoreCase لزيادة السرعة.
  • استخدم عمليات سلسلة StringComparison.CurrentCulture-based عند عرض الإخراج إلى المستخدم.
  • تبديل الاستخدام الحالي لعمليات سلسلة استنادا إلى ثقافة ثابتة لاستخدام StringComparison.Ordinal أو StringComparison.OrdinalIgnoreCase غير لغوية عندما تكون المقارنة
    غير ذات صلة لغويا (رمزية، على سبيل المثال).
  • استخدام ToUpperInvariant بدلا من ToLowerInvariant عند تطبيع سلاسل للمقارنة.

يترك

  • استخدام التحميل الزائد لعمليات السلسلة التي لا تحدد صراحة أو ضمنا آلية مقارنة السلسلة.
  • استخدم سلسلة StringComparison.InvariantCulture القائمة
    العمليات في معظم الحالات؛ واحدة من الاستثناءات القليلة ستكون
    واستمرت البيانات ذات المعنى اللغوي ولكن الملوثة ثقافيا.

استنادا إلى هذه القواعد يجب عليك استخدام:

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

في حين يعتمد [يورديسيسيون] على التوصيات الواردة أعلاه.

لينك أوف سورس: http://msdn.microsoft.com/en-us/library/ms973919.aspx




تماما مثل هذا:

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



وأنا أعلم أن هذا ليس C #، ولكن في إطار (VB.NET) هناك بالفعل مثل هذه الوظيفة

Dim str As String = "UPPERlower"
Dim b As Boolean = InStr(str, "UpperLower")

C # البديل:

string myString = "Hello World";
bool contains = Microsoft.VisualBasic.Strings.InStr(myString, "world");



طريقة إنستر من التجمع فيسوالباسيك هو الأفضل إذا كان لديك قلق حول التدويل (أو هل يمكن إعادة تنفيذه). وبالنظر إلى ذلك في دوتنيتبيك يظهر أن ليس فقط أنها لا تمثل القبعات والصغيرة، ولكن أيضا لنوع كانا وكامل مقابل نصف العرض الأحرف (في الغالب ذات الصلة للغات الآسيوية، على الرغم من أن هناك إصدارات كاملة العرض من الأبجدية الرومانية جدا ). أنا تخطي بعض التفاصيل، ولكن تحقق من الأسلوب الخاص 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);
}



استخدم هذا:

string.Compare("string", "STRING", new System.Globalization.CultureInfo("en-US"), System.Globalization.CompareOptions.IgnoreCase);



في نهاية المطاف، عملية عامة "يحتوي" يأتي إلى وظيفة مثل هذا،

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

الآن، هذا سيعمل على مقارنة ترتيبية من أي تسلسل، بما في ذلك السلاسل، منذ 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. المسألة التي تنطوي على كيفية إشراك مجموعة من "عناصر النص" (أحرف / أرقام / رموز وما إلى ذلك) من خلال نقاط رمز ونيكود وما هي سلاسل صالحة من حرف يمكن أن تمثل سلسلة معينة، يتم توسيع التفاصيل في هذه الإجابات .

التأثير الصافي هو نفسه. السلاسل التي قد تؤكد أنها متساوية لغويا يمكن تمثيلها بشكل صحيح من قبل مجموعات مختلفة من الأحرف. ما هو أكثر من ذلك، قواعد للتغيير صحة بين الثقافات.

كل هذا يؤدي إلى سلسلة متخصصة على أساس "يحتوي على" تنفيذ مثل هذا.

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)



هذا يشبه إلى حد بعيد مثال آخر هنا، ولكن لقد قررت لتبسيط إنوم إلى بول، الابتدائي لأن هناك بدائل أخرى ليست هناك حاجة عادة. وفي ما يلي مثال على ذلك:

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



يعد استخدام ريجيكس طريقة مباشرة للقيام بذلك:

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



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



يمكنك استخدام string.indexof () . هذا سيكون حالة حساسة




الخدعة هنا هي البحث عن السلسلة، وتجاهل القضية، ولكن للحفاظ على نفسه تماما (مع نفس الحالة).

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



إذا كنت تريد أن تحقق ما إذا كانت سلسلة مرت الخاص بك هو في سلسلة ثم هناك طريقة بسيطة لذلك.

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



طريقة بسيطة للمبتدئ:

title.Contains("string") || title.Contains("string".ToUpper());