Domanda

Vorrei rilevare la codifica di un testo (utilizzando PHP). A tal fine io uso mb_detect_encoding function ().

Il problema è che i risultati la funzione restituisce diversi se cambio l'ordine di possibili codifiche con funzione di mb_detect_order ().

Si consideri il seguente esempio

$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'

Tuttavia, se si cambia l'ordine delle codifiche a mb_detect_order () i risultati saranno diversi:

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'


Quindi le mie domande sono:
Perché è successo?
C'è un modo in PHP per rilevare correttamente e senza ambiguità la codifica del testo?

È stato utile?

Soluzione

Questo è ciò che mi aspetto che accada.

L'algoritmo di rilevamento probabilmente solo continua a cercare, in ordine, le codifiche specificate nella mb_detect_order e poi restituisce il primo in cui la bytestream sarebbe valido.

Qualcosa di più intelligente richiede metodi statistici (credo che l'apprendimento automatico è comunemente usato).

EDIT: si veda per es questo articolo per metodi più intelligenti .

  

Per la sua importanza, il rilevamento automatico charset è già implementata nelle principali applicazioni Internet come Mozilla o Internet Explorer. Essi sono molto precisi e veloci, ma la sua attuazione si applica tante conoscenze di dominio specifici, caso per caso. Al contrario di loro metodi, abbiamo puntato ad un semplice algoritmo che può essere applicato in modo uniforme a tutti i set di caratteri, e l'algoritmo è basato su consolidate, tecniche di apprendimento automatico standard. Abbiamo anche studiato la relazione tra il linguaggio e la rilevazione charset, e gli algoritmi di byte a base di rispetto e gli algoritmi basati su caratteri. Abbiamo usato Naive Bayes (NB) e Support Vector Machine (SVM).

Altri suggerimenti

Non proprio. Le diverse codifiche hanno spesso ampie aree di sovrapposizione, e se la stringa che si sta verificando esiste entirly all'interno che si sovrappongono, allora sia la codifica sono accettabili.

Per esempio, utf-8 e ISO-8859-1 sono gli stessi per le lettere a-z. La stringa "ciao" avrebbe una sequenza identica di byte in entrambe le codifiche.

Questo è esattamente il motivo per cui v'è una funzione mb_detect_order(), in primo luogo, in quanto consente di dire ciò che si preferisce che accada quando questi scontri avvengono. Vuoi che "ciao" di essere UTF-8 o ISO-8859-1?

Ricordate mb_detect_encoding() non sa cosa la codifica dei dati è in. Si può vedere una stringa, ma la funzione in sé vede solo un flusso di byte. Andando da questo, ha bisogno di indovinare che cosa è la codifica - per esempio ASCII sarebbe se byte sono solo nella gamma 0-127, UTF-8 sarebbe se ci sono byte ASCII e 128+ byte che esistono solo in coppia o più, e così via.

Come si può immaginare, dato questo contesto, è abbastanza difficile da rilevare una codifica in modo affidabile.

rihk detto, questo è ciò che la funzione mb_detect_order() è per - si sta fondamentalmente fornendo la tua ipotesi migliore ciò che i dati è probabile che sia. Non si lavora con UTF-8 file di frequente? Allora è probabile che la tua roba non è probabile che sia UTF-16, anche se mb_detect_encoding() poteva immaginare come questo.

Si potrebbe anche voler controllare Artefacto 's link per una visione più approfondita.

caso Esempio : Internet Explorer usi un po 'di codifica interessante indovinare se nulla viene specificato (@link, Sezione: 'per rilevare automaticamente la lingua di un sito web') che è causata comportamenti strani sui siti web che hanno avuto la codifica per scontato in passato. Probabilmente si può trovare un po 'roba divertente su che se google in giro. Si fa per una bella vetrina come anche metodi statistici può ritorcersi contro orribilmente, e perché la codifica-guessing in generale è problematica.

mb_detect_encoding esamina la prima voce charset nel mb_detect_order () e poi loop attraverso il vostro ingresso $ html corrispondente carattere per carattere se tale carattere rientra nella serie valida di caratteri per il set di caratteri. Se ogni personaggio corrisponde, allora restituisce true; se qualsiasi personaggio fallisce, si sposta al prossimo set di caratteri nel mb_detect_order () e riprova.

La lista wikipedia dei set di caratteri è un buon posto per vedere i caratteri che compongono ogni charset.

Poiché questi valori charset sovrapposizione (char x8fA1EF esiste sia 'UTF-8' e 'EUC-JP') sarà considerato una corrispondenza anche se è un personaggio totalmente diverso in ogni set di caratteri. Quindi, a meno uno qualsiasi dei valori di carattere esistono in un solo set di caratteri, ma non in un altro, poi mb_detect_encoding non può identificare quale dei set di caratteri non è valido; e tornerà il primo set di caratteri dalla tua lista di array che potrebbe essere valido.

Per quanto io sappia, non c'è modo infallibile per identificare un set di caratteri. Metodo "ipotesi migliore" di PHP può essere aiutato se si dispone di una ragionevole idea di ciò che i set di caratteri si rischia di incontro, e ordinare il vostro elenco di conseguenza in base alle lacune (caratteri non validi) in ogni set di caratteri. La soluzione migliore è quella di "conoscere" il charset. Se si sta raschiando il codice HTML da un'altra pagina, cercare l'identificatore charset nell'intestazione della pagina.

Se si vuole veramente essere intelligente, si può cercare di identificare la lingua in cui è scritto il codice html, magari utilizzando trigrammi o n-grammi o simili come descritto in questo articolo su PHP / ir.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top