I have been trying to figure out a simple way to replace the integers within a string with x's in python. I was able to get something ok by doing the following:
In [73]: string = "martian2015"
In [74]: string = list(string)
In [75]: for n, i in enumerate(string):
....: try:
....: if isinstance(int(i), int):
....: string[n]='x'
....: except ValueError:
....: continue
This actually yields something like the following:
In [81]: string
Out[81]: ['m', 'a', 'r', 't', 'i', 'a', 'n', 'x', 'x', 'x', 'x']
In [86]: joiner = ""
In [87]: string = joiner.join(string)
In [88]: string
Out[88]: 'martianxxxx'
My question is: is there any way of getting the result in a simpler manner without relying on error/exception handling?
Yes, using regex and the re
module:
import re
new_string = re.sub("\d", "x", "martin2015")
The string "\d"
tells Python to search for all digits in the string. The second argument is what you want to replace all matches with, and the third argument is your input. (re.sub
stands for "substitute")
You can use the str.isdigit
function and list comprehension, like this
>>> data = "martian2015"
>>> "".join(["x" if char.isdigit() else char for char in data])
'martianxxxx'
The isdigit
function will return True
if all the characters in it are numeric digits. So, if it is a digit, then we use "x"
otherwise we use the actual character itself.
You can actually use generator expression instead of list comprehension to do the same, like this
>>> "".join("x" if char.isdigit() else char for char in data)
'martianxxxx'
The only difference is generators are lazy evaluated, unlike the list comprehension which builds the entire list. The generator will give values only on demand. Read more about them here.
But in this particular case, with str.join
, the list is built anyway.
If you are going to do this kind of replacement often, then you might want to know about str.translate
and str.maketrans
.
>>> mapping = str.maketrans("0123456789", "x" * 10)
>>> "martin2015".translate(mapping)
'martinxxxx'
>>> "10-03-2015".translate(mapping)
'xx-xx-xxxx'
>>>
The maketrans
builds a dictionary with the character codes of values in the first string and the corresponding character in the second string. So, when we use the mapping
with the translate
, whenever it finds a character in the mapping
, it will simply replace it with the corresponding value.
change isinstance
to .isdigit
string = "martian2015"
for i in string:
if i.isdigit():
string.replace(i, "x")
(or regular expressions, regex / re )
In [102]: import string
In [103]: mystring
Out[103]: 'martian2015'
In [104]: a='x'*10
In [105]: leet=maketrans('0123456789',a)
In [106]: mystring.translate(leet)
Out[106]: 'martianxxxx'
If you don't know advance data process method, you can invoke string
module to filter num string.
import string
old_string = "martin2015"
new_string = "".join([s if s not in string.digits else "x" for s in old_string ])
print new_string
# martinxxxx
Although I know my anwser is not the best solution, I want to offer different methods help people solve problems.