[Az] hiç gebelik / PCRE'nin aksanlı karakterler maç olacak?

3 Cevap php

Zaten \w PCRE'nin (özellikle PHP'nin uygulama) bazen sistemin yerele bağlı bazı ASCII olmayan karakterleri maç farkındayım, ama ne [a-z] hakkında?

Ben öyle düşünmüyorum, ama ben (basitleştirilmiş, / theme.inc içerir) Drupal çekirdek dosyalardan birinde bu satırları fark:

// To avoid illegal characters in the class,
// we're removing everything disallowed. We are not using 'a-z' as that might leave
// in certain international characters (e.g. German umlauts).
$body_classes[] = preg_replace('![^abcdefghijklmnopqrstuvwxyz0-9-_]+!s', '', $class);

Bu doğru mu, ya da birisi sadece \w ile karıştırılmamalıdır [a-z] aldın?

3 Cevap

Uzun lafın kısası: Belki app dağıtıldığında sistemine bağlıdır, PHP, yerelleştirme ve uluslararasılaşma CF hoşgeldiniz derlenmiştir nasıl bağlıdır.

The underlying PCRE engine takes locale into account when determining what "a-z" means. In a Spanish based locale, ñ would be caught by a-z). The semantic meaning of a-z is "all the letters between a and z, and ñ is a separate letter in Spanish.

However, the way PHP blindly handles strings as collections of bytes rather than a collection of UTF code points means you have a situation where a-z MIGHT match an accented character. Drupal dağıtmış olur farklı sistemlerin çeşitliliği göz önüne alındığında, onlar izin karakterler hakkında açık olmak yerine sadece doğru olanı yapmak için, az güven tercih edeceğini mantıklı.

I'd also conjecture that the existence of this regular expression is the result of a bug report being filed about German umlauts not being filtered.

Update in 2014: JimmiTh's answer below, (bazı "kafa karıştırıcı-to-olmayan-pcre-core-geliştiriciler" belgelerine rağmen) gibi görünüyor [a-z] sadece maç olacak Başına karakterler zaman abcdefghijklmnopqrstuvwxyz meşhur bir% 99. O dedi - çerçeve geliştiricilerin kod PHP gibi incelikle istediğiniz gibi idare etmediğini sistemleri (yerele özgü dizeleri) dayanır, özellikle kendi kod belirsizlik hakkında twitchy almak eğilimindedir ve sunucular geliştiriciler üzerinde hiçbir kontrole sahip. Anonim Drupal geliştirici yorumları yanlış olsa - bu "[a-z] \w ile bocalama" meselesi değildi, ama bunun yerine bir Drupal geliştiricisi PCRE ele nasıl emin / belirsiz olmak { [(2)]}, ve daha spesifik formu seçerek abcdefghijklmnopqrstuvwxyz istedikleri belirli bir davranış sağlamak.

comment Drupal kodda olan WRONG.

Bu NOT "international characters (e.g. German umlauts)" Maç olabileceğini doğrudur [a-z] bulunuyor.

Örneğin, mevcut Alman yerel var, varsa, bu gibi kontrol edebilirsiniz:

setlocale(LC_ALL, 'de_DE'); // German locale (not needed, but you never know...)
echo preg_match('/^[a-z]+$/', 'abc') ? "yes\n" : "no\n";
echo preg_match('/^[a-z]+$/', "\xE4bc") ? "yes\n" : "no\n"; // äbc in ISO-8859-1
echo preg_match('/^[a-z]+$/',  "\xC3\xA4bc") ? "yes\n" : "no\n"; // äbc in UTF-8
echo preg_match('/^[a-z]+$/u', "\xC3\xA4bc") ? "yes\n" : "no\n"; // w/ PCRE_UTF8

Çıktı (Eğer de_DE olarak değiştirin eğer değişmeyecek de_DE.UTF-8):

yes
no
no
no

Karakter sınıfı [abcdefghijklmnopqrstuvwxyz] PCRE anlayan hem kodlamalar [a-z] aynıdır: ASCII-türetilmiş monobyte ve (ASCII-türetilmiş too) UTF-8. Bu kodlamalar her ikisinde de [a-z] [\x61-\x7A] ile aynıdır.

Soru 2009 yılında sorulduğunda her şey farklı olabilir, ancak 2014 yılında hiçbir PHP'nin PCRE'nin regex motoru [a-z] fazla 26 karakterden oluşan bir sınıf olarak yorumlamak yapabilirsiniz "garip yapılandırma" (sürece var [a-z] kendisi elbette bir ASCII-türetilmiş kodlamada 5 bayt) olarak yazılır.

Sadece bir iki zaten mükemmel, aykırı ise, cevaplar ek.

PCRE kütüphane dokümantasyon her zaman "aralıkları karakter değerler harmanlama sırayla çalışır" belirtti. Hangi biraz belirsiz ve henüz çok hassas.

Bu index kullanarak mevcut yerel maç kadar ayarlanabilir PCRE'nin dahili karakter tabloları, karakter pcre_maketables . That function builds the tables in order of char value (tolower(i) / {[(tarafından harmanlama anlamına gelir 3)]})

Başka bir deyişle, gerçek kültürel sıralama düzeni (yerel harmanlama bilgi) tarafından harmanlanmıyor değildir. Almanca davranır Sözlük harmanlama o aynı Ø iken bir örnek olarak, ö Alman (ISO-8859-x, unicode kodlamaları vs) için kullanılan tüm ortak karakter kodlamaları az aralığın dışında görünür kılan bir değeri vardır Bu durumda, PCRE ö değil, herhangi bir fiili yerel tanımlı sıralama düzeni daha o kod değeri, üzerine [a-z] aralığında olup olmadığı konusundaki kararlılığını temel olur.

PHP, çoğunlukla PCRE's documentation aynen kopyalanmış olan their docs. Ancak, onlar aslında "aralıkları ASCII karakter sıralamasına faaliyet" için yukarıdaki ifadeyi değiştirerek ağrıları için gittim. Bu açıklama en azından 2004 yılından beri dokümanlar olmuştur.

Yukarıdaki rağmen, ben ancak, bu doğru pek emin değilim.

Eh, her durumda, en azından.

Bir arama PHP yapar pcre_maketables ... Gönderen PHP source:

#if HAVE_SETLOCALE
    if (strcmp(locale, "C"))
        tables = pcre_maketables();
#endif

PHP derlendiği için ortam varsa diğer bir deyişle, setlocale and (LC_CTYPE) yerel POSIX / C yerel değil, çalışma zamanı ortamın POSIX / C yerelin karakter sırasını kullanılır. Aksi halde, varsayılan PCRE tabloları kullanılır - PCRE derlenmiş ({[) (2]}) tarafından oluşturulan hangi - based on the compiler's locale:

Bu function () geçersiz kılmak için bu pcre_compile geçirilebilir. Karakteri az 256 değerleri için karakter tabloları kümesi oluşturur PCRE'nin iç, dahili (PCRE derlenmiş zaman pcre_maketables () tarafından yapılmıştır) tabloları. Eğer standart dışı bir yerel ayarı kullanıyorsanız bunu yapmak isteyebilirsiniz. Fonksiyon tabloları bir işaretçi verir.

Alman herhangi bir ortak karakter kodlaması [a-z] için farklı olmaz ise biz EBCDIC ile ilgili olsaydı, örneğin, [a-z] ± ve ~ içerir. Verilen EBCDIC ben aklınıza gelebilecek bir karakter kodlaması kesintisiz sırayla az ve AZ yer yok olduğunu.

Eğer (çok kendi, çok özel, ısmarlama yerel tanımını kullanarak) en karanlık PHP'nin ya da çalışma ortamı ama bir şey umlauts dahil olurdum derece düşüktür ise, (ve o olabilir) EBCDIC kullanırken PCRE'nin bazı büyü yapar sürece , sen might, EBCDIC durumunda, diğer istenmeyen karakterler içerir. Ve diğer aralıklar için, "ASCII sırayla harmanlanmış" tamamen doğru görünmüyor.

ETA: Ben benzer bir endişe Philip Hazel kendi cevap arayan bazı araştırma kayıtlı olabilir:

Another issue is with character classes ranges. You would think that [a-k] and [x-z] are well defined for latin scripts but that's not the case.

Onlar kesinlikle iyi yani, kültürel sıralama düzeni değil, kod düzeniyle ilgili, [\ x61-\ x6b] ve [\ x78-\ x7a] eşdeğer olmak tanımlanır.