I have a string with which i want to replace any character that isn't a standard character or number such as (a-z or 0-9) with an asterisk. For example, "h^&ell`.,|o w]{+orld" is replaced with "h*ell*o*w*orld". Note that multiple characters such as "^&" get replaced with one asterisk. How would I go about doing this?
Asked
Active
Viewed 1.8e+01k times
136
-
2Possible duplicate of [Stripping everything but alphanumeric chars from a string in Python](http://stackoverflow.com/questions/1276764/stripping-everything-but-alphanumeric-chars-from-a-string-in-python) – sds Nov 03 '16 at 20:23
-
Short example `re.sub(r'\W+', '_', 'bla: bla**(bla)')` replaces one or more consecutive non-alphanumeric characters by an underscore. – Paul Rougieux Oct 14 '21 at 15:33
4 Answers
254
Regex to the rescue!
import re
s = re.sub('[^0-9a-zA-Z]+', '*', s)
Example:
>>> re.sub('[^0-9a-zA-Z]+', '*', 'h^&ell`.,|o w]{+orld')
'h*ell*o*w*orld'

nneonneo
- 171,345
- 36
- 312
- 383
-
7If you handle unicode a lot, you may also need to keep all non-ASCII unicode symbols: `re.sub("[\x00-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]+", " ", ":%# unicode ΣΘΙП@./\n")` – zhazha Jul 13 '16 at 07:43
-
1If you want to keep spaces in your string, just add a space within the brackets: s = re.sub('[^0-9a-zA-Z ]+', '*', s) – stackPusher Oct 20 '16 at 16:31
-
3If doing more than one replace, this will perform slightly quicker if you pre-compile the regex, e.g., `import re; regex = re.compile('[^0-9a-zA-Z]+'); regex.sub('*', 'h^&ell.,|o w]{+orld')` – Chris Jun 02 '18 at 15:47
-
Also note `\W` is for non-word characters, it's almost the same but allows the underscore as a word character (don't know why): https://docs.python.org/3.6/library/re.html#index-32 – JHS Dec 23 '18 at 01:32
-
-
@Serg: The OP wanted to replace multiple consecutive characters with a single `*` - hence, the `+` in the regex. – nneonneo Sep 19 '20 at 00:13
17
Try:
s = filter(str.isalnum, s)
in Python3:
s = ''.join(filter(str.isalnum, s))
Edit: realized that the OP wants to replace non-chars with '*'. My answer does not fit

Don
- 16,928
- 12
- 63
- 101
15
Use \W
which is equivalent to [^a-zA-Z0-9_]
. Check the 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'
update: This solution will exclude underscore as well. If you want only alphabets and numbers to be excluded, then solution by nneonneo is more appropriate.

Csaba Toth
- 10,021
- 5
- 75
- 121

psun
- 615
- 10
- 13
-
2Note that *`\W` is equivalent to `[^a-zA-Z0-9_]`* only in Python 2.x. In Python 3.x, `\W+` is equivalent to `[^a-zA-Z0-9_]` only if `re.ASCII` / `re.A` flag is used. – Wiktor Stribiżew Apr 01 '19 at 20:27
-
Updated [link to the documentation of re](https://docs.python.org/3/library/re.html), search for `\W` in the page "Matches Unicode word characters; this includes most characters that can be part of a word in any language, as well as numbers and the underscore. If the ASCII flag is used, only [a-zA-Z0-9_] is matched." – Paul Rougieux Oct 14 '21 at 15:31