web-dev-qa-db-fra.com

un comportement utf-8 0xc2a0 non perturbant et un comportement étrange

Dans ma chaîne, j’ai l’espace utf-8 (0xc2a0) et je veux le remplacer par quelque chose.

Quand j'utilise

$str=preg_replace('~\xc2\xa0~', 'X', $str);

ça fonctionne bien.

Mais quand j'utilise

$str=preg_replace('~\x{C2A0}~siu', 'W', $str);

espace insécable n'est pas trouvé (et remplacé).

Pourquoi? Quel est le problème avec la deuxième expression rationnelle?

Le format \x{C2A0} est correct, j'ai également utilisé u flag.

31
DamirR

En réalité, la documentation sur les séquences d'échappement dans PHP est incorrecte. Lorsque vous utilisez la syntaxe \xc2\xa0, il recherche le caractère UTF-8. Mais avec la syntaxe \x{c2a0}, il tente de convertir la séquence Unicode en caractère codé UTF-8.

Un espace insécable est U+00A0 (Unicode) mais codé en tant que C2A0 en UTF-8. Donc, si vous essayez avec le modèle ~\x{00a0}~siu, cela fonctionnera comme prévu.

52
Newbo.O

J'ai agrégé les réponses précédentes pour que les gens puissent simplement copier/coller le code suivant pour choisir leur méthode préférée:

$some_text_with_non_breaking_spaces = "some text with 2 non breaking spaces at the beginning";
echo 'Qty non-breaking space : ' . substr_count($some_text_with_non_breaking_spaces, "\xc2\xa0") . '<br>';
echo $some_text_with_non_breaking_spaces . '<br>';

# Method 1 : regular expression
$clean_text = preg_replace('~\x{00a0}~siu', ' ', $some_text_with_non_breaking_spaces);

# Method 2 : convert to bin -> replace -> convert to hex
$clean_text = hex2bin(str_replace('c2a0', '20', bin2hex($some_text_with_non_breaking_spaces)));

# Method 3 : my favorite
$clean_text = str_replace("\xc2\xa0", " ", $some_text_with_non_breaking_spaces);

echo 'Qty non-breaking space : ' . substr_count($clean_text, "\xc2\xa0"). '<br>';
echo $clean_text . '<br>';
12
hugsbrugs

Les deux codes ont des effets différents selon moi: le premier \xc2\xa0 remplacera DEUX caractères, \xc2 et \xa0 par rien.

Dans le codage UTF-8, il s’agit du point de code pour U+00A0.

Est-ce que \x{00A0} fonctionne? Cela devrait être la représentation de \xc2\xa0.

3
DThought

Je n'ai pas travaillé cette variante ~\x{c2a0}~siu.

Varian \x{00A0} fonctionne. Je n'ai pas essayé la deuxième option et voici le résultat:

J'ai essayé de le convertir en hexadécimal et de remplacer l'espace 0xC2 0xA0 (c2a0) sans espace mort par l'espace 0x20 (20).

Code:

$hex = bin2hex($item);
$_item = str_replace('c2a0', '20', $hex);
$item = hex2bin($_item);
1
Pali

/\x {00A0} /,/\ xC2\xA0/et $ clean_hex2bin-str_replace-bin2hex fonctionnaient et ne fonctionnaient pas. Si je l’imprimais à l’écran, c’est bon, mais si j’essayais de le sauvegarder dans un fichier, le fichier serait vide!

J'ai fini par utiliser iconv ('UTF-8', 'ISO-8859-1 // IGNORE', $ str);

0
EllisGL