Question

Je voudrais Détecte un encodage de texte (en utilisant PHP). A cette fin, j'utiliser la fonction mb_detect_encoding ().

Le problème est que la fonction retourne des résultats différents si je change l'ordre des encodages possibles avec la fonction mb_detect_order ().

Prenons l'exemple suivant

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

Toutefois, si vous modifiez l'ordre de codages dans mb_detect_order () les résultats seront différents:

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'


Mes questions sont: Pourquoi est-ce qui se passe?
Est-il possible en PHP pour détecter correctement et sans ambiguïté encodage du texte?

Était-ce utile?

La solution

C'est ce que je compterais arriver.

L'algorithme de détection probablement continue d'essayer, dans l'ordre, les encodages spécifiés dans mb_detect_order puis retourne le premier sous lequel le bytestream serait valable.

Quelque chose de plus intelligente nécessite des méthodes statistiques (je pense que l'apprentissage de la machine est couramment utilisée).

EDIT: Voir par exemple cet article pour des méthodes plus intelligentes .

  

En raison de son importance, la détection automatique de charset est déjà mis en œuvre dans les principales applications Internet telles que Mozilla ou Internet Explorer. Ils sont très précis et rapide, mais la mise en œuvre applique un grand nombre de connaissances spécifiques de domaine en cas par cas. Contrairement à leurs méthodes, nous avons cherché à un algorithme simple qui peut être appliquée uniformément à tous les charset, et l'algorithme est basé sur des techniques d'apprentissage, de la machine standard bien établies. Nous avons également étudié la relation entre le langage et la détection de charset et des algorithmes à base d'octet par rapport et des algorithmes à base de caractères. Nous avons utilisé Naive Bayes (NB) et Support Vector Machine (de SVM).

Autres conseils

Pas vraiment. Les différents encodages ont souvent de vastes zones de chevauchement, et si votre chaîne que vous testez existe entirly à l'intérieur qui se chevauchent, alors l'encodage sont acceptables.

Par exemple, utf-8 et ISO-8859-1 sont les mêmes pour les lettres a-z. La chaîne « bonjour » aurait une séquence identique d'octets dans les deux encodages.

Ceci est exactement la raison pour laquelle il y a une fonction mb_detect_order() en premier lieu, car il vous permet de dire ce que vous préférez arriver lorsque ces affrontements se produisent. Voulez-vous comme "bonjour" être utf-8 ou ISO-8859-1?

Gardez à l'esprit mb_detect_encoding() ne sait pas ce que le codage des données. Vous pouvez voir une chaîne, mais la fonction elle-même ne voit que d'un flux d'octets. Voulez-vous par là, il a besoin de deviner ce que le codage est - par exemple ASCII serait si les octets sont seulement dans la plage de 0 à 127, UTF-8 serait s'il y a des octets ASCII et 128+ octets qui existent uniquement en paires ou plus, et ainsi de suite.

Comme vous pouvez l'imaginer, étant donné ce contexte, il est très difficile de détecter un codage fiable.

Comme rihk dit, ce est ce que la fonction mb_detect_order() est pour - vous fournir essentiellement de votre mieux deviner ce que les données sont susceptibles d'être. Travaillez-vous avec UTF-8 fichiers fréquemment? Ensuite, les chances sont vos affaires ne sont pas susceptibles d'être UTF-16, même si mb_detect_encoding() pouvait deviner comme cela.

Vous pouvez également consulter Artefacto 's lien pour une plus approfondie vue.

cas Exemple : Internet Explorer les utilisations certains d'encodage intéressant deviner si rien n'est spécifié (@link, Section: «pour détecter automatiquement la langue d'un site Web) qui a causé des comportements étranges sur les sites Web qui ont encodant pour acquis dans le passé. Vous pouvez probablement trouver des trucs amusants sur que si vous google autour. Il fait un beau spectacle cas comment même des méthodes statistiques peuvent se retourner contre horriblement, et pourquoi encodage deviner en général est problématique.

mb_detect_encoding regarde la première entrée de jeu de caractères dans votre mb_detect_order () et les boucles puis à travers votre entrée $ correspondant à caractère html par caractère si ce caractère se situe dans l'ensemble valide de caractères pour le jeu de caractères. Si chaque personnage correspond, il retourne vrai; si un caractère échoue, on passe à la prochaine charset dans le mb_detect_order () et tente à nouveau.

La liste de wikipedia de est charsets un bon endroit pour voir les personnages qui composent chaque charset.

Du fait de ces valeurs charset (le charbon x8fA1EF existe dans « UTF-8 » et 'EUC-JP) cela sera considéré comme un match, même si elle est un personnage totalement différent dans chaque jeu de caractères. Donc, à moins que l'une des valeurs de caractères existent dans un charset, mais pas dans un autre, alors mb_detect_encoding ne peut pas identifier des jeux de caractères est invalide; et retournera le premier jeu de caractères de votre liste de tableau qui pourrait être valide.

Pour autant que je sache, il n'y a aucun moyen d'identifier de surefire un charset. méthode « meilleure estimation » de PHP peut être aidé si vous avez une idée raisonnable de ce que vous Charsets êtes susceptible de rencontrer, et commander votre liste en conséquence sur la base des écarts (caractères non valides) dans chaque charset. La meilleure solution est de « connaître » le charset. Si vous racler votre code HTML d'une autre page, recherchez l'identificateur charset dans l'en-tête de cette page.

Si vous voulez vraiment être intelligent, vous pouvez essayer d'identifier la langue dans laquelle le code html est écrit, peut-être en utilisant trigrammes ou n-grammes ou similaire à celle décrite dans cet article sur PHP / ir.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top