¿Función para devolver solo caracteres alfanuméricos de la cadena?

98

Estoy buscando una función php que tome una cadena de entrada y devuelva una versión desinfectada eliminando todos los caracteres especiales y dejando solo alfanuméricos.

Necesito una segunda función que haga lo mismo pero solo devuelva caracteres alfabéticos AZ.

Cualquier ayuda muy apreciada.

Scott B
fuente
¿En qué formulario de normalización Unicode están estos y en quién le gustaría hacer esto?
tchrist
1
Cuando dice AZ y 'alfanumérico', ¿realmente se refiere solo a AZ o desea hacer coincidir todas las letras de todos los idiomas, incluidos los idiomas extranjeros y las escrituras obsoletas?
Mark Byers
Si está haciendo esto para poder hacer una comparación de cadenas sin acentos, está haciendo lo incorrecto.
tchrist
3
Es no sólo “de todos los idiomas”. Su inglés. El inglés usa la escritura latina. Hay unichars '\p{Latin}' '\p{Alphabetic}' '[^A-Za-z]' | wc -l== 1192 puntos de código que son alfabéticos latinos pero que no son AZ. Es un mito común que ASCII es suficiente para el inglés. No lo es, y es por eso que escribir AZ huele a código .
tchrist
1
@Scott B: El inglés no solo usa las 26 letras de AZ. Por ejemplo, la palabra currículum incluye é. Quizás podría explicar lo que está tratando de hacer, ya que esto podría ayudarlo a obtener mejores respuestas.
Mark Byers

Respuestas:

212

Advertencia: Tenga en cuenta que el inglés no se limita solo a AZ.

Intente esto para eliminar todo excepto az, AZ y 0-9:

$result = preg_replace("/[^a-zA-Z0-9]+/", "", $s);

Si su definición de alfanumérico incluye letras en idiomas extranjeros y escrituras obsoletas, deberá utilizar las clases de caracteres Unicode.

Intente esto para dejar solo AZ:

$result = preg_replace("/[^A-Z]+/", "", $s);

La razón de la advertencia es que palabras como currículum contienen la letra éque no coincidirá con esta. Si desea hacer coincidir una lista específica de letras, ajuste la expresión regular para incluir esas letras. Si desea hacer coincidir todas las letras, use las clases de caracteres apropiadas como se menciona en los comentarios.

Mark Byers
fuente
2
No, un alfanumérico es [\p{Alphabetic}\p{Numeric}]. Olvidé la propiedad alfabética PCRE, pero puede aproximarla con [\pL\pM\pN].
tchrist
1
@tchrist: Asumo que debido a que mencionó específicamente a AZ, solo quiere igualar eso, aunque admito que la pregunta podría ser mucho más clara en este punto. Pediré una aclaración.
Mark Byers
1
@ Mark, no estaba discutiendo con la segunda parte de tu respuesta, aunque si no ha descompuesto canónicamente la cadena primero, no funcionará bien. Estaba discutiendo con la primera parte. Además, trato de corregir siempre las expresiones regulares que funcionan en cualquier dato, no solo en ASCII viejo y mohoso. :) De ahí el mantra de que este lado del Milenio, [A-Z]siempre está mal, a veces .
tchrist
1
@Mark Byers, ya veo ... y sí, prefiero el ipero solo tengo que preocuparme por un grupo demográfico inglés ... olvido que mucha gente tiene que pensar en otros idiomas. Por cierto, acabo de notar que eres el usuario de mayor reputación que nunca ha hecho una pregunta. ¡Incluso Jon Skeet ha hecho preguntas antes!
JD Isaacks
1
¿Por qué hay un + al final de la expresión regular? ¿No sería ... lo mismo si lo quitaras?
Dennis
2

En lugar de preg_replaceeso, siempre puede usar las funciones de filtro de PHP usando la filter_var()función con FILTER_SANITIZE_STRING.

Mark Baker
fuente
¿PHP tiene acceso al algoritmo ISO Stringprep? Sé que Perl y Java lo hacen.
tchrist
Creo que la función de filtro de cadena funciona predominantemente con ASCII de 7 bits, pero no me cite al respecto.
Mark Baker
30
Por favor, ¿puede indicarnos una forma explícita de hacer lo que el usuario solicita FILTER_SANITIZE_STRING? Que yo sepa, lo más cercano que se puede archivar de esta manera es con FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH, pero eso no dejará solo letras y números, sino también puntos, barras, porcentajes y todo eso.
Pere
$ iMycleanVar = filter_var ($ sStringWithNumbers, FILTER_SANITIZE_NUMBER_INT);
Sultanos
4
Parece más un comentario que una respuesta. Dé una explicación adecuada mientras escribe una respuesta.
Siraj Alam
0
  1. Santize para números [ 0-9 ] y alfabetos en general [ \ pL ]:
$string = preg_replace("/[^0-9\pL]+/", "", $string)
  1. Santize específicamente para los alfabetos de la A a la Z (no distingue entre mayúsculas y minúsculas) [ a-zA-Z ]:
$string = preg_replace("/[^a-zA-Z]+/", "", $string)
Sky7ure
fuente