Comment supprimer des caractères non alphanumériques?

349

J'ai besoin de supprimer tous les caractères d'une chaîne qui ne sont pas dans l' a-z A-Z 0-9ensemble ou qui ne sont pas des espaces.

Quelqu'un at-il une fonction pour le faire?

zuk1
la source

Réponses:

695

On dirait que vous saviez presque déjà ce que vous vouliez faire, vous l'avez essentiellement défini comme une expression régulière.

preg_replace("/[^A-Za-z0-9 ]/", '', $string);
Chad Birch
la source
8
zuk1: regexbuddy est d'une grande aide pour cela
relipse
2
Voici un exemple si vous souhaitez inclure le trait d'union comme caractère autorisé. J'en avais besoin car j'avais besoin de supprimer les caractères non autorisés d'un nom d'utilisateur Moodle, en fonction des adresses e-mail: preg_replace ("/ [^ a-z0-9 _. @ \ -] /", '', $ string);
Evan Donovan
2
Est-ce que cela fonctionnerait exactement de la même manière avec des apostrophes (guillemets simples) autour de l'expression régulière, au lieu de guillemets (guillemets doubles)? Par exemple:preg_replace('/[^A-Za-z0-9 ]/', '', $string);
2540625
3
Nous voulons des explications à ce sujet :). Les gens viennent ici pour voir pourquoi c'est ainsi. Veuillez également considérer l'explication de Regex! Merci
Pratik
1
Et si nous voulons conserver les caractères accentués?
wonzbak
169

Pour les caractères unicode, c'est:

preg_replace("/[^[:alnum:][:space:]]/u", '', $string);
voondo
la source
salut voondo, qu'est-ce qui se passe avec le truc / ui .. comment tu l'appelles? quelqu'un peut-il me faire la lumière? Je vous remercie.
kebyang
4
Pour plus de précision, ils sont appelés drapeaux. Ils sont placés après le délimiteur de fermeture (dans ce cas, il s'agit de "/", mais il peut s'agir de "~" ou de "@" ou du caractère que vous souhaitez utiliser tant que les délimiteurs d'ouverture et de fermeture sont identiques) et modifiez le comportement de l'expression.
Doktor J
1
Btw, \winclut \det donc le \dn'est pas nécessaire. En outre, cela est faux car cela laissera également des traits de soulignement dans la chaîne résultante (qui est également incluse dans \w).
smathy
2
Il y a toujours une erreur, les classes de caractères doivent se terminer par ':]' donc la ligne correcte serait: preg_replace ("/ [^ [: alnum:] [: espace:]] / ui", '', $ string);
h00ligan
4
Le idrapeau est-il vraiment nécessaire ici puisqu'il [:alnum:]couvre déjà les deux cas?
billynoah
50

L'expression régulière est votre réponse.

$str = preg_replace('/[^a-z\d ]/i', '', $str);
  • Le isignifie insensible à la casse.
  • ^ signifie, ne commence pas par.
  • \d correspond à n'importe quel chiffre.
  • a-zcorrespond à tous les caractères entre aet z. En raison du iparamètre, vous n'avez pas besoin de spécifier a-zet A-Z.
  • Après \dqu'il y ait un espace, les espaces sont donc autorisés dans cette expression régulière.
raspi
la source
3
Nous voulons des explications à ce sujet :). Les gens viennent ici pour voir pourquoi c'est ainsi. Veuillez également considérer l'explication de Regex! Tout le monde n'est pas assez avancé pour savoir ce que vous y avez écrit sans explication. Merci
Pratik
@PratikCJoshi Le i signifie insensible à la casse. ^ signifie, ne commence pas par. \ d correspond à n'importe quel chiffre. az correspond à tous les caractères entre a et z. En raison du paramètre i, vous n'avez pas besoin de spécifier az et AZ. Après \ d, il y a un espace, donc les espaces sont autorisés dans cette expression régulière.
bart
1
Les gens ne lisent pas les commentaires comme réponse. Veuillez mettre à jour la réponse!
Pratik
18

voici un regex vraiment simple pour cela:

\W|_

et utilisé selon vos besoins (avec un /délimiteur de barre oblique).

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

Testez-le ici avec cet excellent outil qui explique ce que fait l'expression régulière:

http://www.regexr.com/

Alex Stephens
la source
1
Vous avez toujours besoin du /udrapeau, sinon les lettres non ascii sont également supprimées.
Xeoncross
Neat mais correspondrait également aux espaces et si cela est souhaité, pourrait probablement doubler les performances en utilisant une classe de caractères et un quantificateur supplémentaire pour un ou plusieurs [\W_]+
bulle de
18

Si vous devez prendre en charge d'autres langues, au lieu de l'AZ classique, vous pouvez utiliser les éléments suivants:

preg_replace('/[^\p{L}\p{N} ]+/', '', $string);
  • [^\p{L}\p{N} ]définit une classe de caractères négée (elle correspondra à un caractère non défini) de:
    • \p{L}: une lettre de n'importe quelle langue.
    • \p{N}: un caractère numérique dans n'importe quel script.
    • : un caractère spatial.
  • + avidement correspond à la classe de caractères entre 1 et un nombre illimité de fois.

Cela préservera les lettres et les chiffres d'autres langues et scripts ainsi que 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} ]+/', '', '你好世界!@£$%^&*()'); // 你好世界

Remarque: Il s'agit d'une question très ancienne, mais toujours pertinente. Je réponds uniquement pour fournir des informations supplémentaires qui pourraient être utiles aux futurs visiteurs.

Jonathon
la source
8
[\W_]+

 

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

Il sélectionne tout non AZ, az, 0-9 et le supprime.

Voir l'exemple ici: https://regexr.com/3h1rj

Intacto
la source
1
que signifie cette expression régulière / [\ W _] + / u?
Ângelo Rigo
\West l'inverse \wdont sont les caractères A-Za-z0-9_. Il \Wcorrespondra donc à tout caractère qui ne l'est pas A-Za-z0-9_et les supprimera. La []est une limite de jeu de caractères . Le +est redondant sur une limite de jeu de caractères mais signifie normalement 1 ou plusieurs caractères. L' uindicateur étend l'expression pour inclure la prise en charge des caractères unicode, ce qui signifie qu'il ne supprimera pas les caractères au-delà du code de caractère 255 tel que ª²³µ. Exemple d'utilisations diverses 3v4l.org/hSVV5 avec des caractères unicode et ascii.
fyrye
2
preg_replace("/\W+/", '', $string)

Vous pouvez le tester ici: http://regexr.com/

TOZ
la source
Selon la réponse de @Alex Stevens, cela n'attire pas les traits de soulignement "_".
Ariel Allon
0

Je cherchais aussi la réponse et mon intention était de nettoyer chaque non-alpha et il ne devrait pas y avoir plus d'un espace.
Donc, j'ai modifié la réponse d'Alex à cela, et cela fonctionne pour moi preg_replace('/[^a-z|\s+]+/i', ' ', $name)
Le regex ci-dessus s'est transformé sy8ed sirajul7_islamen sy ed sirajul islam
Explication: regex ne vérifiera PAS DE A à Z en cas de manière insensible ou plus d'un espace blanc, et il sera converti en un seul espace.

ssi-anik
la source
-2

Vous pouvez diviser la chaîne en caractères et la filtrer.

<?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

?>
zekel
la source
Raison du downvote : 3v4l.org/fqLVZ De plus, l'appel de fonctions (3 + N) sur une chaîne de longueur inconnue semble vraiment peu attrayant par rapport à un preg_replace()appel simple et simple .
mickmackusa