2010-11-19 12 views
1

J'ai un gros fichier, j'ai donc créé un filtre pour supprimer les caractères utf-8 invalides du XML.PHP: suppression des caractères utf-8 invalides en XML en utilisant le filtre

class ValidUTF8XMLFilter extends php_user_filter { 

    protected static $pattern = '/([\x09\x0A\x0D\x20-\x7E]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})|./x'; 

    function filter($in, $out, &$consumed, $closing) 
    { 
     while ($bucket = stream_bucket_make_writeable($in)) { 
      $bucket->data = preg_replace(self::$pattern, '$1', $bucket->data); 
      $consumed += $bucket->datalen; 
      stream_bucket_append($out, $bucket); 
     } 
     return PSFS_PASS_ON; 
    } 
} 

Ce filtre supprimera également les caractères utf-8 non seulement invalides en XML, mais aussi en utf-8. La regex est tirée de Multilingual form encoding. La classe a été prise de cette réponse: How to skip invalid characters in XML file using PHP et réécrite. Le motif de cette réponse ne fonctionnera pas pour les caractères utf-8 invalides, par exemple. 0x1D.

Ce filtre fonctionnera-t-il, dans une situation où les octets invalides commencent à la fin du tampon et se terminent au début du prochain filtrage? Cette situation est-elle possible?

+0

Qu'essayez-vous de faire? Essayez-vous de supprimer les sous-séquences UTF-8 mal formées (en général c'est une mauvaise idée, remplacez-les par des caractères de substitution, mais c'est un autre sujet) ou voulez-vous opérer sur une séquence UTF-8 valide mais supprimer les caractères qui sont illégales en XML (par exemple la plupart des codes de contrôle C0)? – Artefacto

+0

Je souhaite supprimer les usbsequences UTF-8 mal formées et supprimer les caractères qui sont illégaux dans XML. – prostynick

+0

Comment avez-vous obtenu un fichier UTF-8 qui n'est pas un fichier UTF-8? Arrêtez-vous là et reconsidérez vos données. Ils n'ont aucun sens. – tchrist

Répondre

2

Non, je ne pense pas que cela fonctionnera. Il supprimera les séquences valides d'unités de code qui sont réparties entre plusieurs compartiments.

Il ne devrait pas consommer des séquences potentiellement incomplètes à la fin (et, si nécessaire, il ne devrait rien transmettre et retourner PSFS_FEED_ME).

+0

Le problème est, il est difficile de trouver une regex correcte pour trouver cette situation. La deuxième chose est, vous avez dit, que cela enlèvera des séquences valides de code. Est-il possible, qu'il ne dépouillera pas les séquences illégales de code? – prostynick

+1

@pro Non, il n'est pas possible de ne pas supprimer les séquences illégales car une séquence illégale, lorsqu'elle est séparée, ne devient jamais une séquence légale. La raison en est que la spécification Unicode exige que des octets de plomb valides (ou octets dans la gamme ASCII) ne soient jamais considérés comme faisant partie d'une séquence illégale. – Artefacto

+0

@pro Je ne vous recommande pas d'utiliser une regex. Le tableau 3-7 de la spécification unicode vous aidera ici: http://www.unicode.org/versions/Unicode6.0.0/ch03.pdf – Artefacto

Questions connexes