Saltar al contenido

PHP: Cómo eliminar todos los caracteres no imprimibles en un string?

Esta división fue aprobado por nuestros expertos para que tengas la seguridad de la veracidad de nuestra esta crónica.

Solución:

ASCII de 7 bits?

Si su Tardis acaba de aterrizar en 1963, y solo desea los caracteres ASCII imprimibles de 7 bits, puede extraer todo, desde 0-31 y 127-255 con esto:

$string = preg_replace('/[x00-x1Fx7F-xFF]/', '', $string);

Coincide con cualquier cosa en el rango 0-31, 127-255 y lo elimina.

ASCII extendido de 8 bits?

Te caíste en una máquina del tiempo de los bañeras de hidromasaje y estás de vuelta en los ochenta. Si tiene alguna forma de ASCII de 8 bits, es posible que desee mantener los caracteres en el rango 128-255. Un ajuste fácil: solo busque 0-31 y 127

$string = preg_replace('/[x00-x1Fx7F]/', '', $string);

UTF-8?

Ah, bienvenido al siglo XXI. Si tiene una codificación UTF-8 string, entonces el /u El modificador se puede usar en la expresión regular

$string = preg_replace('/[x00-x1Fx7F]/u', '', $string);

Esto solo elimina 0-31 y 127. Esto funciona en ASCII y UTF-8 porque ambos comparten el mismo rango de conjunto de control (como se indica en mgutt a continuación). Estrictamente hablando, esto funcionaría sin el /u modificador. Pero te facilita la vida si quieres eliminar otros caracteres …

Si está tratando con Unicode, hay potencialmente muchos elementos que no se imprimen, pero consideremos uno simple: ESPACIO SIN ROTURA (U + 00A0)

En un UTF-8 string, esto se codificaría como 0xC2A0. Puede buscar y eliminar esa secuencia específica, pero con la /u modificador en su lugar, simplemente puede agregar xA0 a la clase de personaje:

$string = preg_replace('/[x00-x1Fx7FxA0]/u', '', $string);

Anexo: ¿Qué pasa con str_replace?

preg_replace es bastante eficiente, pero si está haciendo mucho esta operación, puede crear un array de caracteres que desea eliminar, y use str_replace como se indica en mgutt a continuación, por ejemplo

//build an array we can re-use across several operations
$badchar=array(
    // control characters
    chr(0), chr(1), chr(2), chr(3), chr(4), chr(5), chr(6), chr(7), chr(8), chr(9), chr(10),
    chr(11), chr(12), chr(13), chr(14), chr(15), chr(16), chr(17), chr(18), chr(19), chr(20),
    chr(21), chr(22), chr(23), chr(24), chr(25), chr(26), chr(27), chr(28), chr(29), chr(30),
    chr(31),
    // non-printing characters
    chr(127)
);

//replace the unwanted chars
$str2 = str_replace($badchar, '', $str);

Intuitivamente, esto parece que sería rápido, pero no siempre es así, definitivamente debes compararlo para ver si te ahorra algo. Hice algunos puntos de referencia en una variedad string longitudes con datos aleatorios, y este patrón surgió usando php 7.0.12

     2 chars str_replace     5.3439ms preg_replace     2.9919ms preg_replace is 44.01% faster
     4 chars str_replace     6.0701ms preg_replace     1.4119ms preg_replace is 76.74% faster
     8 chars str_replace     5.8119ms preg_replace     2.0721ms preg_replace is 64.35% faster
    16 chars str_replace     6.0401ms preg_replace     2.1980ms preg_replace is 63.61% faster
    32 chars str_replace     6.0320ms preg_replace     2.6770ms preg_replace is 55.62% faster
    64 chars str_replace     7.4198ms preg_replace     4.4160ms preg_replace is 40.48% faster
   128 chars str_replace    12.7239ms preg_replace     7.5412ms preg_replace is 40.73% faster
   256 chars str_replace    19.8820ms preg_replace    17.1330ms preg_replace is 13.83% faster
   512 chars str_replace    34.3399ms preg_replace    34.0221ms preg_replace is  0.93% faster
  1024 chars str_replace    57.1141ms preg_replace    67.0300ms str_replace  is 14.79% faster
  2048 chars str_replace    94.7111ms preg_replace   123.3189ms str_replace  is 23.20% faster
  4096 chars str_replace   227.7029ms preg_replace   258.3771ms str_replace  is 11.87% faster
  8192 chars str_replace   506.3410ms preg_replace   555.6269ms str_replace  is  8.87% faster
 16384 chars str_replace  1116.8811ms preg_replace  1098.0589ms preg_replace is  1.69% faster
 32768 chars str_replace  2299.3128ms preg_replace  2222.8632ms preg_replace is  3.32% faster

Los tiempos en sí son para 10000 iteraciones, pero lo que es más interesante son las diferencias relativas. Hasta 512 caracteres, estaba viendo que preg_replace siempre ganaba. En el rango de 1-8kb, str_replace tenía una ventaja marginal.

Pensé que era un resultado interesante, así que incluirlo aquí. Lo importante no es tomar este resultado y usarlo para decidir qué método usar, sino compararlo con sus propios datos y luego decidir.

Muchas de las otras respuestas aquí no tienen en cuenta los caracteres Unicode (por ejemplo, öäüßйȝîûηы ე மி ᚉ ⠛). En este caso, puede utilizar lo siguiente:

$string = preg_replace('/[x00-x08x0Bx0Cx0E-x1Fx7F-x9F]/u', '', $string);

Hay una clase extraña de personajes en el rango. x80-x9F (Justo por encima del rango de caracteres ASCII de 7 bits) que técnicamente son caracteres de control, pero con el tiempo se han utilizado incorrectamente para caracteres imprimibles. Si no tiene ningún problema con estos, puede usar:

$string = preg_replace('/[x00-x08x0Bx0Cx0E-x1Fx7F]/u', '', $string);

Si también desea eliminar los avances de línea, los retornos de carro, las tabulaciones, los espacios sin interrupciones y los guiones suaves, puede usar:

$string = preg_replace('/[x00-x1Fx7F-xA0xAD]/u', '', $string);

Tenga en cuenta que usted debe utilice comillas simples para los ejemplos anteriores.

Si desea eliminar todo excepto los caracteres ASCII básicos imprimibles (se eliminarán todos los caracteres de ejemplo anteriores), puede usar:

$string = preg_replace( '/[^[:print:]]/', '',$string);

Para obtener referencia, consulte http://www.fileformat.info/info/charset/UTF-8/list.htm

Comenzando con PHP 5.2, también tenemos acceso a filter_var, del cual no he visto ninguna mención, así que pensé en tirarlo por ahí. Para usar filter_var para quitar caracteres no imprimibles < 32 and > 127, puedes hacer:

Filtrar caracteres ASCII por debajo de 32

$string = filter_var($input, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW);

Filtrar caracteres ASCII por encima de 127

$string = filter_var($input, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_HIGH);

Pele ambos:

$string = filter_var($input, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW|FILTER_FLAG_STRIP_HIGH);

También puede codificar en html caracteres bajos (nueva línea, tabulación, etc.) mientras elimina los caracteres altos:

$string = filter_var($input, FILTER_UNSAFE_RAW, FILTER_FLAG_ENCODE_LOW|FILTER_FLAG_STRIP_HIGH);

También hay opciones para eliminar HTML, desinfectar correos electrónicos y URL, etc. Por lo tanto, muchas opciones para desinfectar (eliminar datos) e incluso validar (devolver false si no es válido en lugar de eliminarlo silenciosamente).

Higienización: http://php.net/manual/en/filter.filters.sanitize.php

Validación: http://php.net/manual/en/filter.filters.validate.php

Sin embargo, todavía existe el problema, que el FILTER_FLAG_STRIP_LOW eliminará la nueva línea y los retornos de carro, que para un área de texto son caracteres completamente válidos … por lo que algunas de las respuestas Regex, supongo, todavía son necesarias a veces, por ejemplo, después de revisar esto hilo, planeo hacer esto para textareas:

$string = preg_replace( '/[^[:print:]rn]/', '',$input);

Esto parece más legible que una serie de expresiones regulares que se eliminan por rango numérico.

Reseñas y puntuaciones

Si tienes alguna sospecha o disposición de ascender nuestro noticia te invitamos escribir una ilustración y con gusto lo leeremos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *