2011-03-29 21 views
48

Aynı olup olmadığını görmek için iki değişkeni karşılaştırmak istiyorum, ancak bu karşılaştırmanın büyük/küçük harfe duyarlı olmasını istiyorum.Büyük/küçük harf duyarsız dize karşılaştırması

Örneğin, bu harf duyarlı olacaktır:

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

Ama bu yaklaşım nasıl, bu durumda duyarsız olmak istiyorum?

+1

kesinlikle hassas (in), konuşma yalnızca boolean değerleri. Karşılaştırma operatörü demek istedin, '==' bir. –

cevap

82

Bu oldukça basittir; Her iki değişkende de strtolower()'u aramanız yeterlidir.

Unicode veya uluslararası karakter kümeleriyle uğraşmanız gerekirse, mb_strtolower()'u kullanabilirsiniz.

lütfen unutmayın diğer cevaplar sahte olacak herhangi UTF-8 dize için baytlı karakterleri işlemez işlev strcasecmp() —, böylece sonuçlarını kullanarak öneririz.

+0

Teşekkürler, mysql_query() 'de büyük/küçük harf duyarlı WHERE deyimi nasıl yapabilirim biliyor musunuz? –

+1

Genel olarak, MySQL dizgi karşılaştırması *'nın büyük/küçük harf duyarlı olduğunu düşünüyorum. Yani, 'A' = 'a'' doğrudur. Bir referans: http://dev.mysql.com/doc/refman/5.0/en/case-sensitivity.html – syrion

+0

Bu çok garip, çünkü benim için böyle değil. Latin1_swedish_ci dosyasına harmanlama yapıyorum. –

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

Neden:

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

strcasecmp() döner 0 dizeleri (ayrı vaka varyasyonlarından) aynıdır böylece kullanabilirsiniz eğer:

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

Sadece == 0 için test etmeyi unutmayın; Bu, "eğer (strcasecmp ($ var1, $ var2)) {..." yazmak için çok cazip olduğu için karşı sezgiseldir, ancak bu durumda 0, çoğu durumda olduğu gibi yanlış-notqual yerine eşittir. – Chirael

+3

'strcasecmp()', çok baytlı karakterler ile ilgilenmez, bu nedenle Unicode ile baş edemez. – syrion

1

kullanın strcasecmp. dize tek bayt kodlama ise

+0

Diğer cevaplarda da belirtildiği gibi, bu Unicode için bozuldu. – TextGeek

8

, çok basit:-to küçük harf ve-üst:

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

dize UTF-8 ise, Unicode karmaşıklığını dikkate almak zorunda -case işlevi, eğer küçük harf karakteriniz varsa, büyük harfe dönüştürür ve küçük harfe dönüştürürseniz, aynı kod noktasıyla sonlanamazsınız (ve aynı şey, eğer başlarsanız doğrudur) büyük harfli bir karakter).

E.g. ve "i" 'in üst durum varyantı (Latin Capital Letter I, U+0049) "I" olduğu -

  • "İ" (Latin Capital Letter I with Dot Above, U+0130) "i" (Latin Small Letter I, U+0069), alt durum varyantı olarak sahip, bir büyük harf karakter.
  • daha düşük bir harf karakter üst durumda varyant olarak "I" (Latin Capital Letter I, U+0049) ile, bir (Latin Small Letter Dotless I, U+0131) "ı" - ve "I" 'in alt durum değişkeni "i" (Latin Small Letter I, U+0069)

olduğu Yani aynı büyük harf karakterine sahip olsalar bile mb_strtolower('ı') === mb_strtolower('i') yanlış döndürür.Eğer gerçekten bir harf duyarsız dize karşılaştırma işlevi isterseniz, büyük harf VE küçük harf sürümüne karşılaştırmak zorunda: Ben https://codepoints.net (https://dumps.codepoints.net) den Unicode veritabanında bir sorgu çalıştırmak ettik

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

ve ben ve bir küçük harf karakterinin büyük harfinin küçük harfini alırken farklı bir karakter bulduğum 180 kod noktasını ve bir büyük harfin küçük harfinin büyük harfini alırken farklı bir karakter bulduğum 8 kod noktasını buldu

Ama kötüye gider: kullanıcı tarafından görülen aynı grafik kümesi, onu kodlamanın birden fazla yoluna sahip olabilir: "ä "Latin Small Letter a with Diaeresis (U+00E4) veya Latin Small Letter A (U+0061) ve Combining Diaeresis (U+0308) olarak temsil edilebilir - ve bunları bayt düzeyinde karşılaştırırsanız, bu geri dönüş olmaz!

Ancak Unicode'da bunun için bir çözüm var: Normalization! Dört farklı form vardır: NFC, NFD, NFKC, NFKD. Dizi karşılaştırması için NFC ve NFD eşdeğerdir ve NFKC ve NFKD eşdeğerdir. NFKC'yi NFKD'den daha kısa olduğu için alacağım ve "ff" (Latin Small Ligature ff, U+FB00) iki normal "f" ye dönüştürülecektir (ancak 2⁵ ayrıca 25… 'e genişletilecektir).

çıkan fonksiyon haline gelir:

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

unutmayın:

  • Eğer onlar sadece eşit lütfen önce kontrol ederek bu fonksiyonu optimize etmelidir Normalizer
  • için intl paket lazım NFKC, NFKC yerine NFC kullanmak isteyebileceğinden, NFKC, çok fazla biçimlendirme ayrımını kaldırdığı için NFC'yi NFC yerine kullanmak isteyebilirsiniz:
  • r zevkinize
  • Gerçekten bütün bu karmaşıklığı gerekirse, kendiniz için karar vermek zorunda veya bu fonksiyonun daha basit bir varyantını tercih ediyorsanız durum olamaz EĞER çalışmasından dolayı
İlgili konular