¿Cómo eliminar caracteres no alfanuméricos?


349

Necesito eliminar todos los caracteres de una cadena que no están en a-z A-Z 0-9conjunto o no son espacios.

¿Alguien tiene una función para hacer esto?

Respuestas:


695

Parece que ya casi sabías lo que querías hacer, básicamente lo definiste como una expresión regular.

preg_replace("/[^A-Za-z0-9 ]/", '', $string);

8
zuk1: regexbuddy es una gran ayuda con eso
relipse

2
Aquí hay un ejemplo si desea incluir el guión como un carácter permitido. Necesitaba esto porque necesitaba quitar los caracteres no permitidos de un nombre de usuario de Moodle, basado en las direcciones de correo electrónico: preg_replace ("/ [^ a-z0-9 _. @ \ -] /", '', $ string);
Evan Donovan

2
¿Funcionaría exactamente igual con los apóstrofos (comillas simples) alrededor de la expresión regular, en lugar de las comillas (comillas dobles)? Por ejemplo:preg_replace('/[^A-Za-z0-9 ]/', '', $string);
2540625

3
Queremos una explicación sobre esto :). La gente viene aquí para ver por qué es así. ¡Por favor considere la explicación de Regex también! Gracias
Pratik

1
¿Qué pasa si queremos mantener personajes acentuados?
wonzbak

169

Para los caracteres unicode, es:

preg_replace("/[^[:alnum:][:space:]]/u", '', $string);

hola voondo, ¿qué pasa con la cosa / ui ... cómo lo llamas? ¿Alguien puede arrojarme algo de luz? Gracias.
kebyang

44
Para aclarar, se llaman banderas. Se colocan después del delimitador de cierre (en este caso es "/", pero podría ser "~" o "@" o cualquier carácter que desee utilizar siempre que los delimitadores de apertura y cierre sean los mismos) y cambie el comportamiento de la expresión.
Doktor J

1
Por cierto, \wincluye \dy por lo tanto \des innecesario. Además, esto está mal porque también dejará guiones bajos en la cadena resultante (que también se incluye en \w).
inteligente

2
Todavía hay un error en esto, las clases de caracteres deben terminarse con ':]' para que la línea correcta sea: preg_replace ("/ [^ [: alnum:] [: space:]] / ui", '', $ cadena);
h00ligan

44
¿Es irealmente necesaria la bandera aquí [:alnum:]ya que cubre ambos casos?
billynoah

50

La expresión regular es tu respuesta.

$str = preg_replace('/[^a-z\d ]/i', '', $str);
  • Los isoportes para mayúsculas y minúsculas.
  • ^ significa, no comienza con.
  • \d coincide con cualquier dígito.
  • a-zcoincide con todos los caracteres entre ay z. Debido al iparámetro que no tiene que especificar a-zy A-Z.
  • Después de que \dhaya un espacio, se permiten espacios en esta expresión regular.

3
Queremos una explicación sobre esto :). La gente viene aquí para ver por qué es así. ¡Por favor considere la explicación de Regex también! No todos están lo suficientemente avanzados como para saber lo que escribiste allí sin explicación. Gracias
Pratik

@PratikCJoshi La i significa mayúsculas y minúsculas. ^ significa, no comienza con. \ d coincide con cualquier dígito. az coincide con todos los caracteres entre a y z. Debido al parámetro i no tiene que especificar az y AZ. Después de \ d hay un espacio, por lo que se permiten espacios en esta expresión regular.
Bart

1
La gente no lee los comentarios como respuesta. Por favor, actualice la respuesta!
Pratik

18

Aquí hay una expresión regular realmente simple para eso:

\W|_

y se usa según lo necesite (con un /delimitador de barra diagonal).

preg_replace("/\W|_/", '', $string);

Pruébelo aquí con esta gran herramienta que explica lo que está haciendo la expresión regular:

http://www.regexr.com/


1
Todavía necesita la /ubandera; de lo contrario, también se eliminarán las letras que no sean ascii.
Xeoncross

Limpio pero también coincidiría con espacios y, si se desea, probablemente podría duplicar el rendimiento mediante el uso de una clase de personaje y un cuantificador adicional para uno o más [\W_]+
burbuja de burbujas el

18

Si necesita admitir otros idiomas, en lugar del AZ típico, puede usar lo siguiente:

preg_replace('/[^\p{L}\p{N} ]+/', '', $string);
  • [^\p{L}\p{N} ]define una clase de caracteres negada (coincidirá con un carácter que no está definido) de:
    • \p{L}: una carta de cualquier idioma.
    • \p{N}: un carácter numérico en cualquier script.
    • : un personaje espacial.
  • + codiciosamente coincide con la clase de personaje entre 1 e ilimitado veces.

Esto preservará letras y números de otros idiomas y scripts, así como de AZ:

preg_replace('/[^\p{L}\p{N} ]+/', '', 'hello-world'); // helloworld
preg_replace('/[^\p{L}\p{N} ]+/', '', 'abc@~#123-+=öäå'); // abc123öäå
preg_replace('/[^\p{L}\p{N} ]+/', '', '你好世界!@£$%^&*()'); // 你好世界

Nota: Esta es una pregunta muy antigua, pero aún relevante. Estoy respondiendo únicamente para proporcionar información complementaria que pueda ser útil para futuros visitantes.


8
[\W_]+

 

$string = preg_replace("/[\W_]+/u", '', $string);

Selecciona todo, no AZ, az, 0-9 y lo elimina.

Ver ejemplo aquí: https://regexr.com/3h1rj


1
¿Qué significa esta expresión regular / [\ W _] + / u?
Ângelo Rigo

\Wes el inverso de los \wcuales son los caracteres A-Za-z0-9_. Entonces \Wcoincidirá con cualquier personaje que no lo sea A-Za-z0-9_y los eliminará. El []es un límite de juego de caracteres . El +es redundante en un límite de juego de caracteres, pero normalmente significa 1 o más caracteres. El uindicador expande la expresión para incluir compatibilidad con caracteres unicode, lo que significa que no eliminará caracteres más allá del código de caracteres 255 como ª²³µ. Ejemplo de varios usos 3v4l.org/hSVV5 con caracteres unicode y ascii.
fyrye


0

Estaba buscando la respuesta también y mi intención era limpiar cada no alfa y no debería tener más de un espacio.
Entonces, modifiqué la respuesta de Alex a esto, y esto está funcionando para mí. preg_replace('/[^a-z|\s+]+/i', ' ', $name)
La expresión regular anterior se convirtió sy8ed sirajul7_islamen sy ed sirajul islam
Explicación: la expresión regular verificará NO CUALQUIERA de la a a la z en caso de que sea insensible o más de un espacio en blanco, y se convertirá en un solo espacio.


-2

Puede dividir la cadena en caracteres y filtrarla.

<?php 

function filter_alphanum($string) {
    $characters = str_split($string);
    $alphaNumeric = array_filter($characters,"ctype_alnum");
    return join($alphaNumeric);
}

$res = filter_alphanum("a!bc!#123");
print_r($res); // abc123

?>

Motivo del voto negativo : 3v4l.org/fqLVZ Además, llamar a funciones (3 + N) en una cadena de longitud desconocida parece realmente poco atractivo en comparación con una preg_replace()llamada simple y simple .
mickmackusa
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.