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


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

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

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

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


2420
2018-01-14 21:39


मूल


यह मूर्खतापूर्ण कैसे है? क्या आपका मतलब है कि आप स्ट्रिंग पर 2 पास कर रहे हैं? मुझे लगता है कि केस-असंवेदनशील तुलना केवल दो चरणों को जोड़ती है। - Calyth
चूंकि मैं इसे विश्वव्यापी पर उपयोग करूंगा, इसलिए मुझे विदेशी पात्रों को ध्यान में रखना होगा। जैसा कि नीचे दिए गए एक जवाब में बताया गया है, साथ ही साथ डाउनकेसिंग अंतर्राष्ट्रीयकरण के मुद्दों को भी देता है। - Boris Callens
दोनों तारों को ऊपरी-आवरण मूर्खतापूर्ण है, क्योंकि आप दो नए तार बनाते हैं और फिर भी एक केस-संवेदनशील खोज करते हैं। इस तरह के नए तार बनाने में अनावश्यक अतिरिक्त प्रसंस्करण और स्मृति शामिल है, खासकर यदि आप तारों के एक सेट के माध्यम से खोज रहे हैं और आप खोज या स्रोत शर्तों को अनावश्यक रूप से ऊपरी मामले में रखते हैं। इंडेक्सऑफ विधि जो स्ट्रिंग कॉम्परिसन मान के विनिर्देश को बेहतर बनाती है। - Triynko
xkcd.com/979 - Francisco
@ कोलोनेलपैनिक: सही। यदि आप संस्कृति को जानते हैं, तो यह एक समस्या से कम हो जाता है। लेकिन अक्सर, आप या तो नहीं जानते या परवाह नहीं करते हैं। - Boris Callens


जवाब:


स्ट्रिंग का परीक्षण करने के लिए paragraph स्ट्रिंग है word (धन्यवाद @QuarterMeister)

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

कहा पे culture का उदाहरण है CultureInfo उस भाषा का वर्णन करना जिसमें टेक्स्ट लिखा गया है।

यह समाधान पारदर्शी है केस-असंवेदनशीलता की परिभाषा, जो भाषा निर्भर है। उदाहरण के लिए, अंग्रेजी भाषा पात्रों का उपयोग करती है I तथा i नौवें पत्र के ऊपरी और निचले केस संस्करणों के लिए, जबकि तुर्की भाषा इन पात्रों का उपयोग करती है ग्यारहवें और बारहवें पत्र इसके 2 9 अक्षरों के लंबे वर्णमाला का। 'I' का तुर्की ऊपरी केस संस्करण अपरिचित चरित्र 'İ' है।

इस प्रकार तार tin तथा TIN वही शब्द हैं अंग्रेजी में, लेकिन अलग-अलग शब्द तुर्की में। जैसा कि मैं समझता हूं, एक का अर्थ है 'आत्मा' और दूसरा एक ओनाटोपोपिया शब्द है। (तुर्क, अगर मैं गलत हूं, तो कृपया मुझे सही करें, या बेहतर उदाहरण सुझाएं)

सारांशित करने के लिए, आप केवल प्रश्न का जवाब दे सकते हैं 'क्या ये दो तार समान हैं लेकिन विभिन्न मामलों में' यदि आप जानते हैं कि टेक्स्ट किस भाषा में है। यदि आप नहीं जानते हैं, तो आपको एक पंट लेना होगा। सॉफ्टवेयर में अंग्रेजी की विरासत को देखते हुए, आपको शायद सहारा लेना चाहिए CultureInfo.InvariantCulture, क्योंकि यह परिचित तरीकों से गलत होगा।


1088
2018-03-17 18:22



क्यों नहीं culture.CompareInfo.IndexOf(paragraph, word, CompareOptions.IgnoreCase) >= 0? यह सही संस्कृति का उपयोग करता है और मामला असंवेदनशील है, यह अस्थायी लोअरकेस तारों को आवंटित नहीं करता है, और यह इस सवाल से परहेज करता है कि क्या लोअरकेस में परिवर्तित करना और तुलना करना हमेशा एक केस-असंवेदनशील तुलना के समान होता है। - Quartermeister
यह समाधान एक खोज फ़ंक्शन के लिए स्मृति आवंटित करके ढेर को अनावश्यक रूप से प्रदूषित करता है - JaredPar
ToLower () के साथ तुलना करने से केस-असंवेदनशील इंडेक्स से अलग-अलग परिणाम मिलेंगे जब दो अलग-अलग अक्षरों में एक ही लोअरकेस अक्षर होता है। उदाहरण के लिए, यू +0398 "यूनानी कैपिटल लेटर थेटा" या यू + 03 एफ 4 "ग्रीक कैपिटल लेटर थेटा सिंबल" पर यूओ 03 बी 8, "ग्रीक स्मॉल लेटर थेटा" के परिणामस्वरूप टूलोवर () को कॉल करना, लेकिन पूंजी अक्षरों को अलग माना जाता है। दोनों समाधान एक ही पूंजी पत्र के साथ लोअरकेस अक्षरों पर विचार करते हैं, जैसे कि यू +0073 "लैटिन स्मॉल लेटर एस" और यू +017 एफ "लैटिन स्मॉल लेटर लांग एस", इसलिए इंडेक्सऑफ समाधान अधिक सुसंगत लगता है। - Quartermeister
पूर्णता के लिए +1 - स्पष्टीकरण के उचित रूप के साथ उत्तर एकमात्र तरीका है जो उपयोगकर्ता वास्तव में SO से सीखेंगे - TheGeekZn
आपने "ddddfg" क्यों नहीं लिखा था। IndexOf ("Df", StringComparison.OrdinalIgnoreCase)? - Chen


आप इसका उपयोग कर सकते हैं String.IndexOf विधि और पास 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;
    }
}

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

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

उपयोग:

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

2361
2018-01-14 21:44



ग्रेट स्ट्रिंग एक्सटेंशन विधि! मैंने यह निष्पादित किया है कि स्रोत स्ट्रिंग को जांचने के लिए कोई ऑब्जेक्ट संदर्भ त्रुटियों को रोकने के लिए शून्य स्ट्रिंग नहीं है IndexOf ()। - Richard Pursehouse
यह वही उत्तर देता है paragraph.ToLower(culture).Contains(word.ToLower(culture)) साथ में CultureInfo.InvariantCulture और यह किसी स्थानीयकरण के मुद्दों को हल नहीं करता है। चीजों को जटिल क्यों करें? stackoverflow.com/a/15464440/284795 - Colonel Panic
@ कोलोनेल पैनिक ToLower संस्करण में 2 आवंटन शामिल हैं जो तुलना / खोज ऑपरेशन में अनावश्यक हैं। एक ऐसे परिदृश्य में अनावश्यक रूप से आवंटित क्यों करें जिसके लिए इसकी आवश्यकता नहीं है? - JaredPar
@ सेबिस्किट जो काम नहीं करेगा क्योंकि string है एक IEnumerable<char> इसलिए आप सबस्ट्रिंग्स खोजने के लिए इसका उपयोग नहीं कर सकते हैं - JaredPar
चेतावनी का एक शब्द: के लिए डिफ़ॉल्ट string.IndexOf(string) वर्तमान संस्कृति का उपयोग करना है, जबकि डिफ़ॉल्ट के लिए string.Contains(string) ordinal तुलनाकर्ता का उपयोग करना है। जैसा कि हम जानते हैं, पूर्व को बदला जा सकता है, एक लंबे अधिभार को चुनना, जबकि बाद में बदला नहीं जा सकता है। इस असंगतता का परिणाम निम्नलिखित कोड नमूना है: Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; string self = "Waldstrasse"; string value = "straße"; Console.WriteLine(self.Contains(value));/* False */ Console.WriteLine(self.IndexOf(value) >= 0);/* True */ - Jeppe Stig Nielsen


आप उपयोग कर सकते हैं IndexOf() इस तरह:

string title = "STRING";

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

चूंकि 0 (शून्य) एक सूचकांक हो सकता है, तो आप -1 के खिलाफ जांचते हैं।

MSDN

मान की शून्य-आधारित इंडेक्स स्थिति यदि वह स्ट्रिंग पाई जाती है, या -1   अगर यह नही तो। यदि मान स्ट्रिंग है। लक्षण, वापसी मान 0 है।


203
2018-01-14 21:48





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

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

नोटिस

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


116
2017-07-28 17:18



अच्छा विचार, हमारे पास RegexOptions जैसे बहुत से bitwise संयोजन हैं RegexOptions.IgnoreCase & RegexOptions.IgnorePatternWhitespace & RegexOptions.CultureInvariant; अगर मदद करता है तो किसी के लिए। - Saravanan
कहना चाहिए कि मैं इस विधि को पसंद करता हूं हालांकि स्वच्छता के लिए IsMatch का उपयोग करना। - wonea
इससे भी बदतर, चूंकि सर्च स्ट्रिंग को रेगेक्स के रूप में व्याख्या किया जाता है, इसलिए कई विराम चिह्नों के गलत परिणाम होंगे (या अमान्य अभिव्यक्ति के कारण अपवाद ट्रिगर करेंगे)। खोजने की कोशिश करो "." में "This is a sample string that doesn't contain the search string"। या खोज करने की कोशिश करो "(invalid", उस बात के लिए। - cHao
@cHao: उस मामले में, Regex.Escape मदद कर सका। रेगेक्स अभी भी अनावश्यक लगता है IndexOf / विस्तार Contains सरल है (और तर्कसंगत रूप से अधिक स्पष्ट)। - Dan Mangiarelli
ध्यान दें कि मैं यह नहीं कह रहा था कि यह रेगेक्स समाधान जाने का सबसे अच्छा तरीका था। मैं बस मूल पोस्ट किए गए प्रश्न के उत्तर की सूची में जोड़ रहा था "क्या निम्नलिखित रिटर्न सही करने का कोई तरीका है?"। - Jed


आप हमेशा तारों को पहले ऊपर या नीचे कर सकते हैं।

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

ओह, बस आखिरी बिट देखा। एक मामला असंवेदनशील तुलना होगी *शायद* वैसे भी वही करें, और यदि प्रदर्शन कोई मुद्दा नहीं है, तो मुझे अपरकेस प्रतियां बनाने और उनसे तुलना करने में कोई समस्या नहीं दिखाई देती है। मैं शपथ ले सकता था कि मैंने एक बार एक मामले-असंवेदनशील तुलना एक बार देखा ...


63
2018-01-14 21:42



दिलचस्प बात यह है कि मैंने ToUpper () को इस प्रकार के परिदृश्य में ToLower () के उपयोग पर अनुशंसित किया है, क्योंकि स्पष्ट रूप से ToLower () कुछ संस्कृतियों में "निष्ठा खो सकता है" - यानी, दो अलग-अलग ऊपरी-केस वर्ण समान अनुवाद करते हैं छोटे अक्षर की लिपि। - Matt Hamilton
"तुर्की परीक्षण" के लिए खोजें :) - Jon Skeet
कुछ फ्रांसीसी लोकेशंस में, अपरकेस अक्षरों में डायक्रिटिक्स नहीं होते हैं, इसलिए ToUpper () ToLower () से बेहतर नहीं हो सकता है। मैं कहूंगा कि उचित उपकरण का उपयोग अगर वे उपलब्ध हैं - केस-असंवेदनशील तुलना। - Blair Conrad
ToUpper या ToLower का उपयोग न करें, और जो करें जॉन स्कीट ने कहा - Peter Gfader
बस दो साल बाद एक नया डाउनवोट देखा और फिर भी, मैं सहमत हूं कि तारों की तुलना करने के बेहतर तरीके हैं। हालांकि, सभी कार्यक्रमों को स्थानीयकृत नहीं किया जाएगा (अधिकतर नहीं) और कई आंतरिक या फेंकने वाले ऐप्स हैं। चूंकि मैं शायद ही कभी फेंकने वाले ऐप्स के लिए सबसे अच्छी सलाह के लिए क्रेडिट की उम्मीद कर सकता हूं ... मैं आगे बढ़ रहा हूं: डी - Ed S.


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

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

48
2017-12-07 21:11



यदि चेक चेक खाली स्ट्रिंग है तो इसमें दस्तावेज़ों के अनुसार सही वापस लौटने की आवश्यकता है: "यदि सही पैरामीटर इस स्ट्रिंग के भीतर होता है, या यदि मान खाली स्ट्रिंग (" ") है, अन्यथा, गलत।" - amurra
ऊपर अमूर की टिप्पणी के आधार पर, क्या सुझाए गए कोड को सही करने की आवश्यकता नहीं है? और इसे स्वीकार किए गए उत्तर में नहीं जोड़ा जाना चाहिए, ताकि सबसे अच्छी प्रतिक्रिया पहले हो? - David White
अब यह सत्य वापस आ जाएगा यदि स्रोत एक खाली स्ट्रिंग या शून्य है चाहे कोई भी जांच न हो। यह सही नहीं हो सकता है। अगर इंडेक्स एक खाली स्ट्रिंग है और स्रोत शून्य नहीं है तो इंडेक्सऑफ पहले से ही सच हो जाता है। यहां जरूरी चीज की आवश्यकता है। मेरा सुझाव है कि अगर (स्रोत == शून्य] मूल्य == शून्य) झूठी वापसी; - Colin
स्रोत शून्य नहीं हो सकता है - Lucas
if (string.IsNullOrEmpty(source)) return string.IsNullOrEmpty(toCheck); - Kyle Delaney


स्ट्रिंग एक्स्टेंशन क्लास आगे बढ़ने का तरीका है, मैंने एक पूर्ण कोड उदाहरण देने के लिए उपर्युक्त पदों को जोड़ा है:

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

32
2017-11-18 16:48





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

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

31
2017-11-09 04:25



हालांकि, यह एक पैटर्न के खिलाफ मैच होगा। आपके उदाहरण में, अगर fileNamestr कोई विशेष रेगेक्स वर्ण हैं (उदा। *, +, ., आदि) तो आप काफी आश्चर्यचकित होंगे। इस समाधान को उचित बनाने के लिए एकमात्र तरीका है Contains समारोह से बचने के लिए है fileNamestr ऐसा करके Regex.Escape(fileNamestr)। - XåpplI'-I0llwlg'I -


OrdinalIgnoreCase, CurrentCultureIgnoreCase या InvariantCultureIgnoreCase?

चूंकि यह गुम है, यहां कुछ सिफारिशें दी गई हैं कि किस का उपयोग करना है:

डॉस

  • उपयोग StringComparison.OrdinalIgnoreCase तुलना के लिए संस्कृति-अज्ञेयवादी स्ट्रिंग मिलान के लिए आपके सुरक्षित डिफ़ॉल्ट के रूप में।
  • उपयोग StringComparison.OrdinalIgnoreCase तुलना बढ़ी हुई गति के लिए।
  • उपयोग StringComparison.CurrentCulture-based स्ट्रिंग ऑपरेशन उपयोगकर्ता को आउटपुट प्रदर्शित करते समय।
  • Invariant के आधार पर स्ट्रिंग ऑपरेशंस के वर्तमान उपयोग को स्विच करें गैर भाषाई का उपयोग करने के लिए संस्कृति 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
}

जबकि [YourDecision] ऊपर से सिफारिशों पर निर्भर करता है।

स्रोत का लिंक: http://msdn.microsoft.com/en-us/library/ms973919.aspx


24
2018-06-17 10:31



क्या होगा यदि आप जानते हैं कि आप हमेशा अंग्रेजी स्ट्रिंग प्राप्त करेंगे। किस का उपयोग करना है? - BKSpurgeon
@BKSpurgeon यदि मामला कोई फर्क नहीं पड़ता है, तो मैं ऑर्डिनल इग्नोरकेस का उपयोग करूंगा - Fabian Bigler


सिर्फ इस तरह:

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

12
2017-07-13 09:54



यह संस्कृति-विशिष्ट नहीं है और कुछ मामलों के लिए असफल हो सकता है। culture.CompareInfo.IndexOf (अनुच्छेद, शब्द, तुलनाऑप्शन। इग्नोरकेस) का उपयोग किया जाना चाहिए। - hikalkan
स्ट्रिंग से बचें। कम करने के लिए () केस-असंवेदनशील स्ट्रिंग तुलना करते समय? Tl डॉ यह महंगा है क्योंकि एक नई स्ट्रिंग "निर्मित" है। - Liam


मुझे पता है कि यह सी # नहीं है, लेकिन ढांचे में (वीबीएनईटी) पहले से ही ऐसा एक समारोह है

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

सी # संस्करण:

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

10
2017-09-09 13:23



क्या आप यह भी जानते हैं कि यह आंतरिक रूप से कैसे काम करता है? - Boris Callens