PHP mb_detect_order garip davranış ()

4 Cevap php

I would like to detect encoding of some text (using PHP). For that purpose i use mb_detect_encoding() function.

Sorun i mb_detect_order () fonksiyonu ile mümkündür kodlamaları sırasını değiştirirseniz işlevi farklı sonuçlar verir olmasıdır.

Aşağıdaki örneği inceleyin

$html = <<< STR
ちょっとのアクセスで落ちてしまったり、サーバー障害が多いレンタルサーバーを選ぶとあなたのビジネス等にかなりの影響がでてしまう可能性があります。特に商売をされている個人の方、法人の方は気をつけるようにしてください
STR;
mb_detect_order(array('UTF-8','EUC-JP', 'SJIS', 'eucJP-win', 'SJIS-win', 'JIS', 'ISO-2022-JP','ISO-8859-1','ISO-8859-2'));
$originalEncoding = mb_detect_encoding($str);
die($originalEncoding); // $originalEncoding = 'UTF-8'

Eğer mb_detect_order içinde kodlamaları sırasını değiştirmek Ancak () sonuçları farklı olacaktır:

mb_detect_order(array('EUC-JP','UTF-8', 'SJIS', 'eucJP-win', 'SJIS-win', 'JIS', 'ISO-2022-JP','ISO-8859-1','ISO-8859-2'));        
die($originalEncoding); // $originalEncoding = 'EUC-JP'



So my questions are:
Why is that happening ?
Is there a way in PHP to correctly and unambiguously detect encoding of text ?

4 Cevap

Ben ne beklediğiniz bulunuyor.

Algılama algoritması muhtemelen sadece sırayla, daha sonra mb_detect_order belirtilen ve kodlamaları bayt akışı geçerli olacağını altında ilk birini verir, çalışırken tutar.

Daha akıllı bir şey (ben makine öğrenme yaygın olarak kullanılan düşünüyorum) istatistiksel yöntemler gerektirir.

DÜZENLEME: örneğin, bakınız this article daha zeki yöntemleri.

Önemi nedeniyle, otomatik charset algılama zaten böyle Mozilla veya Internet Explorer gibi büyük Internet uygulamaları uygulanmaktadır. Bunlar çok doğru ve hızlı, ancak uygulama vaka-by-case bazında birçok etki alanı belirli bilgilerin geçerlidir. Kendi yöntemleri aksine, biz düzgün her charset uygulanabilir basit bir algoritma amaçlayan, ve algoritma köklü, standart makine öğrenme teknikleri dayanmaktadır. Biz de dil ve charset algılama ve karşılaştırılmıştır bayt-tabanlı algoritmalar ve karakter-tabanlı algoritmalar arasındaki ilişkiyi inceledi. Biz Naive Bayes (NB) ve Destek Vektör Makinesi (DVM) kullanılır.

Gerçekten değil. Farklı kodlamaları genellikle örtüşme geniş alanlar var, ve sen test sizin dize bu örtüşme içinde entirly varsa, o zaman her iki kodlama kabul edilebilir.

Örneğin, utf-8 ve ISO-8859-1 az harf için aynıdır. Dizesi "merhaba" hem kodlamalar bayt özdeş dizisi olurdu.

Siz bu çatışmalar ne zaman ne için tercih olacağını söylemek için izin verdiği ilk etapta bir mb_detect_order() fonksiyonu, orada tam olarak budur. Eğer utf-8 veya ISO-8859-1 olarak "merhaba" ister misiniz?

mb_detect_encoding() bir dize görebilirsiniz içeri veri kodlama ne olduğunu bilmiyor akılda tutmak, ancak kendisi işlevi tek bir bayt akışı görür. - Örneğin bu giderek, bu kodlama ne olduğunu tahmin etmek gerekiyor ASCII benzeri byte 0-127 aralığında sadece eğer, UTF-8 çift veya daha fazla, ancak mevcut ASCII byte ve 128 + byte varsa olurdunuz, ve olacaktır.

Tahmin edebileceğiniz gibi, bu bağlamda verilen, güvenilir bir kodlama tespit etmek oldukça zordur.

Temelde veri olması muhtemeldir Sanırım ne iyi tedarik konum - rihk Dediğim gibi, bunun için mb_detect_order() fonksiyonu budur. Sık sık UTF-8 dosyaları ile çalışır mı? O şansı şeyler mb_detect_encoding() bu kadar tahmin ettim bile UTF-16 olması muhtemel değildir vardır.

Ayrıca daha derinlemesine görünüm için link Artefacto 's kontrol etmek isteyebilirsiniz.

Example case: hafife kodlama aldı sitelerinde garip davranışlar neden olduğunu: Internet Explorer hiçbir şey belirtilmemişse ('otomatik bir web sitesi dili algılamak için,' @ link, Bölüm) tahmin bazı ilginç kodlama kullanır Geçmişte. Etrafında google eğer, muhtemelen bu konuda bazı eğlenceli şeyler bulabilirsiniz. Hatta istatistiksel yöntemler korkunç geri tepebilir nasıl güzel bir gösteri-case için yapar, ve neden kodlama-tahmin genelde sorunludur.

mb_detect_encoding sizin mb_detect_order ilk charset girişi bakar () ve daha sonra bu karakter charset için karakter geçerli kümesi içinde olup olmadığını karakteri tarafından giriş $ html uyan karakteri aracılığıyla döngüler. Her karakter uyuyorsa, o zaman true döndürür; herhangi bir karakter başarısız olursa, o mb_detect_order sonraki charset geçer () ve yeniden dener.

The wikipedia list of charsets Her charset oluşturan karakterleri görmek için iyi bir yerdir.

Bu charset değerler (char x8fA1EF hem 'UTF-8' ve 'EUC-JP' in var) üst üste çünkü bu her karakter kümesinden tamamen farklı bir karakter olsa da, bir maç olarak kabul edilecektir. Karakter değerlerinden herhangi biri charset var, ancak başka bir sürece Yani, o mb_detect_encoding geçersiz karakter setlerinin hangi tespit edemez; ve geçerli olabilir sizin dizi listeden ilk charset dönecektir.

As far as I'm aware, there is no surefire way of identifying a charset. PHP's "best guess" method can be helped if you have a reasonable idea of what charsets you are likely to encounter, and order your list accordingly based on the gaps (invalid characters) in each charset. The best solution is to "know" the charset. If you are scraping your html from another page, look for the charset identifier in the header of that page.

Eğer gerçekten zeki olmak istiyorsanız, deneyebileceğiniz ve PHP / IR üzerinde this article anlatıldığı gibi belki trigramlari veya n-gram veya benzeri kullanarak, html yazıldığı dili tanımlamak.