Remplacer tous les caractères non alphanumériques dans une chaîne

100

J'ai une chaîne avec laquelle je veux remplacer tout caractère qui n'est pas un caractère standard ou un nombre tel que (az ou 0-9) par un astérisque. Par exemple, "h ^ & ell`., | Ow] {+ orld" est remplacé par "h * ell * o * w * orld". Notez que plusieurs caractères tels que "^ &" sont remplacés par un astérisque. Comment pourrais-je procéder?

tchadwik
la source

Réponses:

184

Regex à la rescousse!

import re

s = re.sub('[^0-9a-zA-Z]+', '*', s)

Exemple:

>>> re.sub('[^0-9a-zA-Z]+', '*', 'h^&ell`.,|o w]{+orld')
'h*ell*o*w*orld'
nneonneo
la source
7
Si vous manipulez beaucoup l'Unicode, vous devrez peut-être également conserver tous les symboles Unicode non ASCII:re.sub("[\x00-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]+", " ", ":%# unicode ΣΘΙП@./\n")
zhazha
Si vous souhaitez conserver des espaces dans votre chaîne, ajoutez simplement un espace entre les crochets: s = re.sub ('[^ 0-9a-zA-Z] +', '*', s)
stackPusher
2
Si vous faites plus d'un remplacement, cela fonctionnera légèrement plus rapidement si vous précompilez le regex, par exemple,import re; regex = re.compile('[^0-9a-zA-Z]+'); regex.sub('*', 'h^&ell.,|o w]{+orld')
Chris
Notez également que \Wpour les caractères autres que des mots, c'est presque la même chose mais permet le trait de soulignement comme caractère de mot (je ne sais pas pourquoi): docs.python.org/3.6/library/re.html#index-32
JHS
37

La voie pythonique.

print "".join([ c if c.isalnum() else "*" for c in s ])

Cela ne concerne pas le regroupement de plusieurs caractères consécutifs non correspondants, c'est-à-dire

"h^&i => "h**ipas "h*i"comme dans les solutions regex.

baloan
la source
11

Essayer:

s = filter(str.isalnum, s)

en Python3:

s = ''.join(filter(str.isalnum, s))

Edit: réalisé que l'OP veut remplacer les non-caractères par '*'. Ma réponse ne correspond pas

Don
la source
11

Utilisez \Wce qui équivaut à [^a-zA-Z0-9_]. Consultez la documentation, https://docs.python.org/2/library/re.html

Import re
s =  'h^&ell`.,|o w]{+orld'
replaced_string = re.sub(r'\W+', '*', s)
output: 'h*ell*o*w*orld'

mise à jour: cette solution exclura également le trait de soulignement. Si vous voulez que seuls les alphabets et les nombres soient exclus, alors la solution par nneonneo est plus appropriée.

psun
la source
1
Notez que cela \Wéquivaut[^a-zA-Z0-9_] uniquement à Python 2.x. En Python 3.x, \W+équivaut à [^a-zA-Z0-9_]seulement si re.ASCII/re.A flag est utilisé.
Wiktor Stribiżew