.Contains() بدون مراعاة حالة الأحرف في C#: أفضل 5 طرق في 2025

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

لماذا سيفشلك .Contains() العادي (وكيف تصلح ذلك)

تخيل: أنت تكتب بحثًا في كتالوج الكتب بلغة C#. المستخدم يدخل "Толстой"، ولكن في قاعدة البيانات مخزنة "толстой" بحرف صغير. string.Contains("Толстой") العادي سيعيد false. ألم مألوف؟ هذا السؤال حصد آلاف المشاهدات على Stack Overflow - وليس بدون سبب. في عام 2025، عندما تقدم .NET أدوات قوية للتعامل مع السلاسل النصية، فإن استخدام النهج القديم يعني خسارة المستخدمين والأداء.

في هذه المقالة، سنستعرض أفضل 5 طرق لجعل .Contains() غير حساس لحالة الأحرف في C#. ستعرف أي طريقة تختار لأقصى سرعة، وأيها للعمل الصحيح مع اللغات المختلفة. هيا بنا!

المشكلة: لماذا يكون .Contains() حساسًا لحالة الأحرف افتراضيًا؟

في C#، تستخدم طريقة string.Contains() افتراضيًا مقارنة Ordinal. هذا يعني أن الأحرف تُقارن بايتًا بايت: 'A' (0x41) لا يساوي 'a' (0x61). بالنسبة للمحتوى الإنجليزي، غالبًا ما يكون هذا طبيعيًا، ولكن في التطبيقات متعددة اللغات (الروسية، الألمانية، التركية) يكسر هذا النهج منطق البحث.

على سبيل المثال، في اللغة التركية، الحرف 'i' في حالة الأحرف الكبيرة هو 'İ' وليس 'I'. استخدام ToLower() العادي قد يعطي نتيجة غير صحيحة. لذلك، مجرد استدعاء text.ToLower().Contains(pattern.ToLower()) هو ممارسة سيئة. دعنا نلقي نظرة على الحلول الحديثة.

الطريقة 1: StringComparison.OrdinalIgnoreCase - معيارك الجديد

بدءًا من .NET 5 (وتعمل بشكل ممتاز في .NET 8/9)، أسرع وأكثر طريقة آمنة هي استخدام التحميل الزائد Contains مع المعامل StringComparison:

string text = "Война и мир — Лев Толстой";
string searchTerm = "толстой";

bool result = text.Contains(searchTerm, StringComparison.OrdinalIgnoreCase);
Console.WriteLine(result); // True

لماذا هو الخيار الأفضل؟

  • السرعة: يعمل OrdinalIgnoreCase على مستوى البايت، لكنه يتجاهل حالة الأحرف. هذا أسرع بمقدار 2-3 مرات من CurrentCultureIgnoreCase.
  • القابلية للتنبؤ: لا يعتمد على ثقافة المستخدم. "ß" (Eszett الألمانية) لن تساوي "ss" إذا كنت لا تريد ذلك.
  • الدعم: متوفر في جميع الإصدارات الحديثة من .NET (Core 2.1+).

استخدم هذه الطريقة عندما تحتاج إلى مقارنة بسيطة بدون مراعاة حالة الأحرف، ولا تعمل مع الخصائص اللغوية (الترتيب، التصريفات).

الطريقة 2: IndexOf() مع StringComparison - إذا كنت بحاجة إلى تحكم أكبر

أحيانًا لا تحتاج فقط إلى التحقق من الوجود، بل أيضًا إلى معرفة موضع التواجد. أو تعمل مع إصدارات أقدم من .NET Framework حيث لا يتوفر Contains مع StringComparison. هنا يأتي دور IndexOf():

string text = "C# — лучший язык для backend";
string searchTerm = "Лучший";

bool result = text.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase) >= 0;
Console.WriteLine(result); // True

// وإذا كنت بحاجة للحصول على الموضع:
int index = text.IndexOf(searchTerm, StringComparison.OrdinalIgnoreCase);
Console.WriteLine(index); // 4 (الموضع الذي تبدأ منه الكلمة)

متى تستخدم:

  • في المشاريع القديمة (مثل .NET Framework 4.x).
  • عندما تحتاج إلى العثور على فهرس التواجد، وليس فقط التحقق من الوجود.
  • للسيناريوهات الأكثر تعقيدًا (مثل البحث مع تخطي الأحرف).

هام: IndexOf يعيد -1 إذا لم يتم العثور على السلسلة الفرعية. تحقق دائمًا من >= 0، وليس > 0.

الطريقة 3: CultureInfo.CurrentCultureIgnoreCase - للبحث الصحيح لغويًا

إذا كان تطبيقك يجب أن يراعي

المدونات

توصيات الكتب