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.