7
votes

Comportement étrange de MB_Detect_Order () en PHP

Je voudrais détecter le codage d'un texte (en utilisant PHP). Pour cette fin, j'utilise mb_detect_encoding () fonction.

Le problème est que la fonction renvoie des résultats différents si je modifie l'ordre des codages possibles avec MB_Detect_Order () Fonction MB_Detect_Order ().

Considérez l'exemple suivant . > xxx

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



Donc, mes questions sont:

Pourquoi cela se passe-t-il?
Y a-t-il un moyen de détecter correctement et sans ambiguïté le codage du texte?


0 commentaires

4 Réponses :


5
votes

C'est ce que j'attendrais.

L'algorithme de détection continue probablement d'essayer, dans l'ordre, les codages que vous avez spécifiés dans mb_detect_order puis renvoie le premier sous lequel le bytream serait valide.

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

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à mise en œuvre dans les principales applications Internet telles que Mozilla ou Internet Explorer. Ils sont très précis et rapides, mais la mise en œuvre applique de nombreuses connaissances spécifiques à un domaine au cas par cas. Contrairement à leurs méthodes, nous visons un algorithme simple qui peut être appliqué de manière uniforme à chaque brict, et l'algorithme est basé sur des techniques d'apprentissage de machines standard bien établies. Nous avons également étudié la relation entre la détection de langue et de charset et nous comparé des algorithmes basés sur des octets et des algorithmes basés sur des caractères. Nous avons utilisé NAIVE BAYES (NB) et supportez la machine de vecteur (SVM).


0 commentaires

5
votes

Pas vraiment. Les différents codages ont souvent de grandes zones de chevauchement et si votre chaîne que vous testez est entièrement à l'intérieur de ce chevauchement, les deux codages sont acceptables.

Par exemple, UTF-8 et ISO-8859-1 sont les mêmes pour les lettres A-Z. La chaîne "Hello" aurait une séquence identique d'octets dans les deux codages.

C'est exactement pourquoi il y a une fonction mb_detect_order () en premier lieu, car elle vous permet de dire ce que vous préféreriez arriver lorsque ces affrontements se produisent. Souhaitez-vous "Bonjour" d'être UTF-8 ou ISO-8859-1?


2 commentaires

Je suppose qu'il y a beaucoup de symboles qui se chevauchent dans 2 codages différents. Si oui, comment puis-je sélectionner le codage qui convient le mieux au texte? En d'autres termes - "Comment sélectionner un codage à l'aide du texte particulier pourrait être codé sans perte de données"?


Je choisirais d'abord le codage le plus flexible et le dernier le dernier. Donc, je préférerais UTF-8, car cela encodera du texte japonais, ainsi que de toutes les autres langues, tandis que quelque chose comme ISO-8859-1 pourrait sembler approprié pour un échantillon de texte donné, il risque de poser des problèmes si vous vouliez ajouter caractères non européens. Vraiment, si vous avez affaire à de nombreux ensembles de personnages internationaux et que vous ne savez pas ce qu'ils seront à l'avance, pourquoi essayer de détecter du tout - utilisez simplement quelque chose qui fonctionnera toujours.



1
votes

mb_detect_encoding examine la première entrée de charset dans votre MB_Detect_Order (), puis bouclez le caractère de correspondant HTML d'entrée $ par caractère si ce caractère tombe dans le jeu de caractères valide pour le Charset. Si chaque personnage correspond, alors il retourne vrai; Si un caractère échoue, il passe au prochain crst dans le MB_Detect_Order () et tente à nouveau.

La liste Wikipedia de Charèsets est un bon endroit pour voir les personnages qui composent chacun Charset.

Parce que ces valeurs de brandon se chevauchent (CHAR X8FA1EFI dans "UTF-8" et "EUC-JP"), cela sera considéré comme une correspondance même s'il s'agit d'un caractère totalement différent de chaque ensemble de caractères. Donc, à moins que l'une des valeurs de caractère n'existe dans une brictorale, mais pas dans une autre, MB_Detect_encoding ne peut pas identifier lequel des caractères n'a pas été invalide; et retournera le premier Charset de votre liste de matrices qui pourrait être valide.

Aussi loin que je sache, il n'y a pas de moyen Sansfire d'identifier un brict. La méthode «Meilleure Guess» de PHP peut être aidée si vous avez une idée raisonnable de ce que vous êtes susceptible de rencontrer et de commander votre liste en conséquence sur la base des lacunes (caractères non valides) dans chaque brict. La meilleure solution consiste à "savoir" le ménage. Si vous grattez votre HTML à partir d'une autre page, recherchez l'identifiant 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 HTML est écrit, peut-être utiliser des trigrammes ou des n grammes ou similaires comme décrit dans Cet article sur PHP / IR.


0 commentaires

2
votes

garder à l'esprit mb_detect_encoding () ne sait pas ce qui codant dans les données. Vous pouvez voir une chaîne, mais la fonction elle-même ne voit que un flux d'octets. Aller à cela, il doit deviner ce que le codage est - par exemple ASCII serait si des octets ne sont que dans la gamme 0-127, UTF-8 serait s'il ya exister des octets ASCII et plus de 128 octets qui n'existent que par paires ou plus, et ainsi de suite.

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

J'aime Rihk a dit: C'est ce que la fonction mb_detect_order () est pour - vous fournissez fondamentalement de votre mieux que les données sont susceptibles d'être. Travaillez-vous fréquemment avec des fichiers UTF-8? Ensuite, il y a de chances que vos affaires ne soient probablement pas utf-16 même si mb_detect_encoding () pourrait le deviner comme ça.

Vous voudrez peut-être aussi consulter artefacto < / a> 's lien Pour une vue plus en profondeur.

exemple de cas : Internet Explorer utilise des devinements de codage intéressants si rien n'est spécifié (@Link, section: "Pour détecter automatiquement la langue d'un site") a provoqué des comportements étranges sur des sites Web qui ont pris un codage pour l'octroi du passé. Vous pouvez probablement trouver des choses amusantes sur cela si vous google. Cela fait une belle émission de savoir comment même des méthodes statistiques peuvent se retourner d'horriblement et pourquoi le codage - devinette en général est problématique.


0 commentaires