2012-10-11 24 views
28

En mi cadena tengo espacio utf-8 non-breaking (0xc2a0) y quiero reemplazarlo con algo más.non-breaking utf-8 0xc2a0 espacio y preg_replace comportamiento extraño

Cuando uso

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

funciona bien.

Pero cuando uso no se encuentra

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

espacio de no separación (y reemplazado).

¿Por qué? ¿Qué pasa con la segunda expresión regular?

El formato \x{C2A0} es correcto, también usé la bandera u.

+0

Puede ser porque '$ str' no es Unicode cuerda. – YOU

Respuesta

46

En realidad, la documentación sobre las secuencias de escape en PHP es incorrecta. Cuando usa la sintaxis \xc2\xa0, busca el carácter UTF-8. Pero con la sintaxis \x{c2a0}, intenta convertir la secuencia Unicode al carácter codificado UTF-8.

Un espacio sin división es U+00A0 (Unicode) pero codificado como C2A0 en UTF-8. Entonces, si prueba con el patrón ~\x{00a0}~siu, funcionará como se esperaba.

+0

Sí, \ x {00a0} funciona, gracias. – DamirR

+1

Hola, Newbo. Tu respuesta funcionó para mí, pero todavía no entiendo por qué. ¿Es porque mi nbsp no es UTF-8? Mis datos provienen de una tabla de base de datos con el conjunto de caracteres utf8_general_ci, por lo que debe ser UTF-8 (mi character_set_client y character_set_connection también son UTF-8). ¿Tiene un enlace para obtener más información sobre esto? Gracias. –

+3

[Este artículo] (http://rrn.dk/the-difference-between-utf-8-and-unicode) es excelente para entender más sobre este tema. También hay [esta pregunta SO] (http://stackoverflow.com/questions/3951722/whats-the-difference-between-unicode-and-utf8) donde el anterior artículo ha sido copiado/pegado. –

3

Los dos códigos hacen cosas diferentes en mi opinión: el primer \ xc2 \ xa0 reemplazará DOS caracteres, \ xc2 y \ xa0 sin nada.

En codificación UTF-8, este pasa a ser el punto de código para U + 00A0

no \ x {} 00A0 funciona? Esta debería ser la representación de \ xc2 \ xa0

+0

\ x {00a0} funciona, gracias. – DamirR

1

No funcioné esta variante ~\x{c2a0}~siu.

Varian \x{00A0} funciona. No he probado la segunda opción y aquí está el resultado:

He intentado convertirlo a hexadecimal y reemplazar el espacio sin interrupción 0xC2 0xA0 (c2a0) al espacio 0x20 (20).

Código:

$hex = bin2hex($item); 
$_item = str_replace('c2a0', '20', $hex); 
$item = hex2bin($_item); 
+0

Gracias, funciona ... – realmag777

10

tengo respuestas anteriores aggegate así que la gente puede copiar/pegar siguiente código de elegir su método favorito:

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