2011-03-29 20 views
48

मैं दो चरों की तुलना करना चाहता हूं यह देखने के लिए कि वे समान हैं या नहीं, लेकिन मैं यह तुलना केस-असंवेदनशील होना चाहता हूं।केस असंवेदनशील स्ट्रिंग तुलना

उदाहरण के लिए, इस मामले संवेदनशील होगा:

if($var1 == $var2){ 
    ... 
} 

लेकिन मैं इस मामले असंवेदनशील होना चाहता हूँ, मैं यह कैसे दृष्टिकोण होगा?

+1

सख्ती से बोल, (में) संवेदनशील यदि ऐसा नहीं हो सकता है, के रूप में यह संचालित केवल बूलियन मूल्य। यह तुलना ऑपरेटर का मतलब है, '== 'एक। –

उत्तर

82

यह काफी सरल है; आपको बस दोनों चरों पर strtolower() पर कॉल करने की आवश्यकता है।

यदि आपको यूनिकोड या अंतरराष्ट्रीय चरित्र सेट से निपटने की आवश्यकता है, तो आप mb_strtolower() का उपयोग कर सकते हैं।

कृपया ध्यान दें कि अन्य उत्तर का उपयोग कर strcasecmp() — कि ढंग से काम multibyte वर्ण संभाल नहीं करता है, किसी भी UTF-8 स्ट्रिंग के लिए तो परिणाम फर्जी हो जाएगा सुझाव देते हैं।

+0

धन्यवाद, क्या आप यह भी जान लेंगे कि मैं mysql_query() में केस-असंवेदनशील कहां कर सकता हूं? –

+1

सामान्य रूप से, मेरा मानना ​​है कि MySQL स्ट्रिंग तुलना * है * केस-असंवेदनशील। यही कहना है, 'ए' = 'ए' सच है। एक संदर्भ: http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html – syrion

+0

यह बहुत अजीब है, क्योंकि यह मेरे लिए यह नहीं करता है। मैंने latin1_swedish_ci पर संयोजन स्थापित किया है। –

2
if(strtolower($var1) == strtolower($var2)){ 
} 
0

नहीं क्यों:

if(strtolower($var1) == strtolower($var2)){ 
} 
57

strcasecmp() रिटर्न 0 तार (मामले विविधताओं से अलग) ही कर रहे हैं तो आप उपयोग कर सकते हैं:

if (strcasecmp($var1, $var2) == 0) { 
} 
+3

बस == 0 के लिए परीक्षण करना याद रखें; यह काउंटर-अंतर्ज्ञानी है क्योंकि यह लिखने के लिए बहुत मोहक है "अगर (strcasecmp ($ var1, $ var2)) {..." लेकिन इस मामले में 0 झूठी-नोटक्वल के बजाए बराबर है, जैसा कि अक्सर होता है। – Chirael

+3

'strcasecmp()' multibyte वर्णों से निपटता नहीं है, इसलिए यह यूनिकोड से निपट नहीं सकता है। – syrion

1

उपयोग strcasecmp

+0

जैसा कि अन्य उत्तरों के साथ उल्लेख किया गया है, यह यूनिकोड के लिए टूटा हुआ है। – TextGeek

8

अपने स्ट्रिंग एक एकल बाइट एन्कोडिंग में है, तो यह आसान है: करने के लिए लोअर केस और करने के लिए ऊपरी: अपने स्ट्रिंग UTF-8 है

if(strtolower($var1) === strtolower($var2)) 

, आप यूनिकोड की जटिलता पर विचार करने के लिए है -केस जैविक कार्य नहीं हैं, यानी यदि आपके पास कम केस कैरेक्टर है, तो इसे ऊपरी मामले में बदलें, और इसे वापस कम मामले में बदलें, आप एक ही कोड पॉइंट के साथ समाप्त नहीं हो सकते हैं (और यदि आप साथ शुरू करते हैं तो वही सच है एक ऊपरी केस चरित्र)।

उदा। और "मैं" के अपर केस संस्करण "मैं" (Latin Capital Letter I, U+0049) है -

  • "मैं" (Latin Capital Letter I with Dot Above, U+0130) एक अपर केस चरित्र, के साथ "मैं" (Latin Small Letter I, U+0069) ने अपने छोटे अक्षर उपादानों के रूप में है।
  • "मैं" (Latin Small Letter Dotless I, U+0131) एक लोअर केस वर्ण "मैं" (Latin Capital Letter I, U+0049) इसके ऊपरी मामले उपादानों के रूप में के साथ, है - और "मैं" के लोअर केस संस्करण (Latin Small Letter I, U+0069)

है "i" तो mb_strtolower('ı') === mb_strtolower('i') झूठी वापसी करता है, भले ही उनके पास समान ऊपरी केस कैरेक्टर हो।क्या तुम सच में एक केस-संवेदी स्ट्रिंग तुलना समारोह चाहते हैं, आप अपर केस तथा लोअर केस संस्करण के लिए तुलना करने के लिए है:

if(mb_strtolower($string1) === mb_strtolower($string2) 
    || mb_strtoupper($string1) === mb_strtoupper($string2)) 

मैं https://codepoints.net (https://dumps.codepoints.net) से यूनिकोड डेटाबेस के खिलाफ एक क्वेरी चलाने की है और मैं 180 कोड बिंदु है जिसके लिए मैं एक अलग चरित्र है जब एक लोअर केस वर्ण के अपर केस के निचले मामले को ले, और 8 कोड बिंदु है जिसके लिए मैं एक अलग चरित्र पाया पाया जब एक बड़े अक्षर के लोअर केस के ऊपरी मामले को ले पाया है

लेकिन यह खराब हो जाता है: उपयोगकर्ता द्वारा देखी गई एक ही ग्रैफेम क्लस्टर में एन्कोडिंग के कई तरीके हो सकते हैं: "ä "Latin Small Letter a with Diaeresis (U+00E4) या Latin Small Letter A (U+0061) और Combining Diaeresis (U+0308) के रूप में प्रदर्शित किया जा सकता है - और यदि आप उन्हें बाइट स्तर पर तुलना करते हैं, तो यह सच नहीं होगा!

लेकिन यूनिकोड में इसके लिए एक समाधान है: Normalization! चार अलग-अलग रूप हैं: एनएफसी, एनएफडी, एनएफकेसी, एनएफकेडी। स्ट्रिंग तुलना के लिए, एनएफसी और एनएफडी बराबर हैं और एनएफकेसी और एनएफकेडी बराबर हैं। मैं एनएफकेसी लेता हूं क्योंकि यह एनएफकेडी से छोटा है, और "एफएफ" (Latin Small Ligature ff, U+FB00) दो सामान्य "एफ" में परिवर्तित हो जाएगा (लेकिन 2⁵ को 25 तक बढ़ाया जाएगा ...)।

जिसके परिणामस्वरूप समारोह हो जाता है:

function mb_is_string_equal_ci($string1, $string2) { 
    $string1_normalized = Normalizer::normalize($string1, Normalizer::FORM_KC); 
    $string2_normalized = Normalizer::normalize($string2, Normalizer::FORM_KC); 
    return mb_strtolower($string1_normalized) === mb_strtolower($string2_normalized) 
      || mb_strtoupper($string1_normalized) === mb_strtoupper($string2_normalized); 
} 

कृपया ध्यान दें:

  • आप Normalizer
  • के लिए intl पैकेज की जरूरत है जब आप पहली बार पता चल सके कि वे सिर्फ बराबर कर रहे हैं द्वारा इस समारोह का अनुकूलन करना चाहिए ^^
  • आप एनएफकेसी के बजाय एनएफसी का उपयोग करना चाह सकते हैं, क्योंकि एनएफकेसी बहुत अधिक स्वरूपण भेद को हटा देता है आर अपने स्वाद
  • आप यदि आप वास्तव में यह सब जटिलता की जरूरत है, खुद के लिए तय करने के लिए है या यदि आप इस समारोह का एक सरल संस्करण पसंद करते हैं
संबंधित मुद्दे