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'
Answer from nneonneo on Stack OverflowRegex 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'
The pythonic way.
print "".join([ c if c.isalnum() else "*" for c in s ])
This doesn't deal with grouping multiple consecutive non-matching characters though, i.e.
"h^&i => "h**i not "h*i" as in the regex solutions.
regex - Replace non alphanumeric characters except some exceptions python - Stack Overflow
Stripping everything but alphanumeric chars from a string in Python - Stack Overflow
Replacing non-alphanumeric characters in regex match using Python - Stack Overflow
Python Regex - Replacing Non-Alphanumeric Characters AND Spaces with Dash - Stack Overflow
You can specify everything that you need not remove in the negated character clas.
re.sub(r'[^\w'+removelist+']', '',mystring)
Test
>>> import re
>>> removelist = "=."
>>> mystring = "asdf1234=.!@#$"
>>> re.sub(r'[^\w'+removelist+']', '',mystring)
'asdf1234=.'
Here the removelist variable is a string which contains the list of all characters you need to exclude from the removal.
What does negated character class means
When the ^ is moved into the character class it does not acts as an anchor where as it negates the character class.
That is ^ in inside a character class say like [^abc] it negates the meaning of the character class.
For example [abc] will match a b or c where as [^abc] will not match a b or c. Which can also be phrased as anything other than a b or c
re.sub(r'[^a-zA-Z0-9=]', '',mystring)
You can add whatever you want like _ whichever you want to save.
I just timed some functions out of curiosity. In these tests I'm removing non-alphanumeric characters from the string string.printable (part of the built-in string module). The use of compiled '[\W_]+' and pattern.sub('', str) was found to be fastest.
$ python -m timeit -s \
"import string" \
"''.join(ch for ch in string.printable if ch.isalnum())"
10000 loops, best of 3: 57.6 usec per loop
$ python -m timeit -s \
"import string" \
"filter(str.isalnum, string.printable)"
10000 loops, best of 3: 37.9 usec per loop
$ python -m timeit -s \
"import re, string" \
"re.sub('[\W_]', '', string.printable)"
10000 loops, best of 3: 27.5 usec per loop
$ python -m timeit -s \
"import re, string" \
"re.sub('[\W_]+', '', string.printable)"
100000 loops, best of 3: 15 usec per loop
$ python -m timeit -s \
"import re, string; pattern = re.compile('[\W_]+')" \
"pattern.sub('', string.printable)"
100000 loops, best of 3: 11.2 usec per loop
Regular expressions to the rescue:
import re
re.sub(r'\W+', '', your_string)
By Python definition
'\W==[^a-zA-Z0-9_], which excludes allnumbers,lettersand_
You were very close. You just don't need the + , because then that would would replace multiple occurances with just one dash.
You need:
re.sub('[^0-9a-zA-Z]', '-', s)
Example:
import re
s = 'ABCDE : CE ; CUSTOMER : Account Number; New Sales'
print(re.sub('[^0-9a-zA-Z]', '-', s))
# ABCDE---CE---CUSTOMER---Account-Number--New-Sales
I see spaces translated properly, but your regexp should omit the +
import re
s = 'ABCDE : CE ; CUSTOMER : Account Number; New Sales'
re.sub('[^0-9a-zA-Z]+', '-', s)
I'm on my phone, but pasting that into https://repl.it/languages/python3 gives me
ABCDE-CE-CUSTOMER-Account-Number-New-Sales
as expected - spaces translated.
If you want the multiple - characters, lose the + in your regexp:
import re
s = 'ABCDE : CE ; CUSTOMER : Account Number; New Sales'
re.sub('[^0-9a-zA-Z]', '-', s)
Gives
ABCDE---CE---CUSTOMER---Account-Number--New-Sales
FYI I do want to keep the commas between strings in the list. Here is my code right now. I've been working on this for hours and I'm stuck, I can't figure it out. I working on a program that will append every string of at least four characters to a new list. I'm going to use this to run through some ebooks I have in .txt
def parse(s):
listOfWords = []
i = 0
final = s.lower()
final = final.split()
while i < len(final):
if len(final[i]) >= 4:
listOfWords.append(final[i])
i = i + 1
return listOfWordsCurrent Output
['lincolnโs', 'silly,', 'flat', 'dishwatery', 'utterances', 'chicago', 'times,', '1863']
Desired Output
["lincoln", "silly", "flat", "dishwatery", "utterances", "chicago", "times"]
Something like that is perfect for regular expressions. re.sub takes as input a regular expression that defines what to match, a string (or a function) to decide what to replace what is matched with, and a string to do all this matching and replacing on. As an example:
import re
string = "lincoln's silly flat dishwatery utterances chicago times 1863"
print re.sub(r'[^a-zA-Z ]', '', string).split()
# ouputs:
# ['lincolns', 'silly', 'flat', 'dishwatery', 'utterances', 'chicago', 'times']
This will replace all characters that are not between lowercase a-z, uppercase A-Z, or a space, with nothing -- essentially removing them.
Use isAlpha() on each character.