J'ai un problème avec la suppression des caractères non utf8 de la chaîne, qui ne s'affichent pas correctement. Les caractères sont comme ceci 0x97 0x61 0x6C 0x6F (représentation hexadécimale)
Quelle est la meilleure façon de les supprimer? Expression régulière ou autre chose?
Réponses:
En utilisant une approche regex:
Il recherche les séquences UTF-8 et les capture dans le groupe 1. Il correspond également à des octets uniques qui n'ont pas pu être identifiés comme faisant partie d'une séquence UTF-8, mais ne les capture pas. Le remplacement est ce qui a été capturé dans le groupe 1. Cela supprime efficacement tous les octets non valides.
Il est possible de réparer la chaîne en codant les octets invalides en caractères UTF-8. Mais si les erreurs sont aléatoires, cela pourrait laisser des symboles étranges.
ÉDITER:
!empty(x)
correspondra aux valeurs non vides ("0"
est considéré comme vide).x != ""
correspondra aux valeurs non vides, y compris"0"
.x !== ""
correspondra à tout sauf""
.x != ""
semble le meilleur à utiliser dans ce cas.J'ai aussi un peu accéléré le match. Au lieu de faire correspondre chaque caractère séparément, il correspond aux séquences de caractères UTF-8 valides.
la source
$regex = <<<'END'
pour PHP <5.3.x?elseif (!empty($captures([2])) {
et vous devriez utiliser!== ""
au lieu de vide car"0"
est considéré comme vide. Cette fonction est également très lente, cela pourrait-il être fait plus rapidement?Si vous appliquez
utf8_encode()
à une chaîne déjà UTF8, il renverra une sortie UTF8 déformée.J'ai créé une fonction qui aborde tous ces problèmes. Ça s'appelle
Encoding::toUTF8()
.Vous n'avez pas besoin de savoir quel est l'encodage de vos chaînes. Il peut s'agir de Latin1 (ISO8859-1), Windows-1252 ou UTF8, ou la chaîne peut en avoir un mélange.
Encoding::toUTF8()
convertira tout en UTF8.Je l'ai fait parce qu'un service me donnait un flux de données tout foiré, mélangeant ces encodages dans la même chaîne.
Usage:
J'ai inclus une autre fonction, Encoding :: fixUTF8 (), qui corrigera chaque chaîne UTF8 qui semble être un produit déformé d'avoir été encodée en UTF8 plusieurs fois.
Usage:
Exemples:
affichera:
Télécharger:
https://github.com/neitanod/forceutf8
la source
Vous pouvez utiliser mbstring:
... supprimera les caractères invalides.
Voir: Remplacement des caractères UTF-8 non valides par des points d'interrogation, mbstring.substitute_character semble ignoré
la source
<0x1a>
<0x1a>
, bien que non imprimable, c'est une séquence UTF-8 parfaitement valide. Vous pourriez avoir des problèmes avec les caractères non imprimables? Vérifiez ceci: stackoverflow.com/questions/1176904/…ini_set('mbstring.substitute_character', 'none');
sinon j'obtenais des points d'interrogation dans le résultat.Cette fonction supprime tous les caractères NON ASCII, c'est utile mais ne résout pas la question:
c'est ma fonction qui fonctionne toujours, quel que soit l'encodage:
Comment ça fonctionne:
la source
í
caractère dans le champ d'adresse qui EST un caractère UTF-8 valide voir tableau . Le moral: ne faites pas confiance aux messages d'erreur de l'API :)C'est ce que j'utilise. Semble fonctionner plutôt bien. Tiré de http://planetozh.com/blog/2005/01/remove-invalid-characters-in-utf-8/
la source
essaye ça:
Selon le manuel iconv , la fonction prendra le premier paramètre comme jeu de caractères d'entrée, le deuxième paramètre comme jeu de caractères de sortie et le troisième comme chaîne d'entrée réelle.
Si vous définissez à la fois le jeu de caractères d'entrée et de sortie sur UTF-8 et que vous ajoutez l'
//IGNORE
indicateur au jeu de caractères de sortie, la fonction supprime (supprime) tous les caractères de la chaîne d'entrée qui ne peuvent pas être représentés par le jeu de caractères de sortie. Ainsi, filtrage de la chaîne d'entrée en vigueur.la source
//IGNORE
ne semble pas supprimer l'avis selon lequel un UTF-8 invalide est présent (ce que, bien sûr, je connais et que je veux corriger). Un commentaire très apprécié dans le manuel semble penser que c'est un bogue depuis quelques années.iconv
. @halfer Peut-être que vos données d'entrée ne proviennent pas d'utf-8. Une autre option consiste à effectuer une reconversion en ascii puis de nouveau à utf-8. Dans mon cas, j'ai utiliséiconv
comme$output = iconv("UTF-8//", "ISO-8859-1//IGNORE", $input );
Le texte peut contenir des caractères non utf8 . Essayez d'abord de faire:
Vous pouvez en savoir plus ici: http://php.net/manual/en/function.mb-convert-encoding.php news
la source
UConverter peut être utilisé depuis PHP 5.5. UConverter est le meilleur choix si vous utilisez l'extension intl et n'utilisez pas mbstring.
htmlspecialchars peut être utilisé pour supprimer une séquence d'octets invalide depuis PHP 5.4. Htmlspecialchars est meilleur que preg_match pour gérer une grande taille d'octet et la précision. Une grande partie de l'implémentation incorrecte en utilisant une expression régulière peut être vue.
la source
J'ai créé une fonction qui supprime les caractères UTF-8 invalides d'une chaîne. Je l'utilise pour clarifier la description de 27000 produits avant de générer le fichier d'exportation XML.
la source
ord()
renvoie des résultats compris entre 0 et 255. Le géantif
de cette fonction teste les plages unicode quiord()
ne reviendront jamais. Si quelqu'un veut clarifier pourquoi cette fonction fonctionne de cette manière, j'apprécierais la perspicacité.Bienvenue dans 2019 et le
/u
modificateur de regex qui gérera les caractères multioctets UTF-8 pour vousSi vous utilisez uniquement,
mb_convert_encoding($value, 'UTF-8', 'UTF-8')
vous vous retrouverez toujours avec des caractères non imprimables dans votre chaîneCette méthode:
mb_convert_encoding
\r
,\x00
(NULL-byte) et les autres caractères de contrôle avecpreg_replace
méthode:
[:print:]
faire correspondre tous les caractères et\n
nouvelles lignes imprimables et supprimer tout le resteVous pouvez voir le tableau ASCII ci-dessous. Les caractères imprimables vont de 32 à 127, mais le saut de ligne
\n
fait partie des caractères de contrôle qui vont de 0 à 31, nous devons donc ajouter une nouvelle ligne à l'expression régulière/[^[:print:]\n]/u
Vous pouvez essayer d'envoyer des chaînes via l'expression régulière avec des caractères en dehors de la plage imprimable comme
\x7F
(DEL),\x1B
(Esc) etc. et voir comment ils sont suppriméshttps://www.tehplayground.com/q5sJ3FOddhv1atpR
la source
php-mbstring
n'est pas emballé en php par défaut.la source
Du patch récent au module d'analyseur JSON Feeds de Drupal:
Si vous êtes concerné, oui, il conserve les espaces comme caractères valides.
J'ai fait ce dont j'avais besoin. Il supprime les caractères emoji répandus de nos jours qui ne rentrent pas dans le jeu de caractères 'utf8' de MySQL et qui m'ont donné des erreurs comme "SQLSTATE [HY000]: Erreur générale: 1366 Valeur de chaîne incorrecte".
Pour plus de détails, voir https://www.drupal.org/node/1824506#comment-6881382
la source
iconv
bien mieux que l'ancienne expression rationnellepreg_replace
, qui est aujourd'hui obsolète.ereg_replace()
, désolé.Peut-être pas la solution la plus précise, mais elle fait le travail avec une seule ligne de code:
utf8_decode
convertira les caractères en point d'interrogation;str_replace
supprimera les points d'interrogation.la source
Ainsi, les règles sont que le premier octlet UTF-8 a le bit haut défini comme marqueur, puis 1 à 4 bits pour indiquer le nombre d'octlets supplémentaires; alors chacun des octets supplémentaires doit avoir les deux bits hauts mis à 10.
Le pseudo-python serait:
Cette même logique devrait être traduisible en php. Cependant, il n'est pas clair quel type de décapage doit être fait une fois que vous avez un personnage mal formé.
la source
c = (ch << 1)
fera(c & 1)
zéro la première fois, en sautant la boucle. Le test devrait probablement être(c & 128)
Pour supprimer tous les caractères Unicode en dehors du plan de langage de base Unicode:
la source
Légèrement différent de la question, mais ce que je fais est d'utiliser HtmlEncode (string),
pseudo code ici
entrée et sortie
Je sais que ce n'est pas parfait, mais fait le travail pour moi.
la source
ça marche sur notre service
la source
Que diriez-vous d'iconv:
http://php.net/manual/en/function.iconv.php
Je ne l'ai pas utilisé dans PHP lui-même, mais il a toujours bien fonctionné pour moi sur la ligne de commande. Vous pouvez l'obtenir pour remplacer des caractères invalides.
la source