So there are following things which are wrong in your pattern, let's address them first

  • A-z - It includes all the character from ascii table starting from A to z, which also has non alphabetical characters which we don't want to match, so the correct one should be [A-Z] if we want only uppercase, if we want both upper and lowercase then it should be [A-Za-z] or you can turn on i flag
  • ^\s - ^ means negation only when you use it as first character inside the character class elsewhere it is treated as literal ^

So your regex should be

 [^A-Za-z\s]
Answer from Code Maniac on Stack Overflow
Discussions

regex - Python, remove all non-alphabet chars from string - Stack Overflow
I am writing a python MapReduce word count program. Problem is that there are many non-alphabet chars strewn about in the data, I have found this post Stripping everything but alphanumeric chars fr... More on stackoverflow.com
🌐 stackoverflow.com
Regex match all non letters excluding diacritics (python) - Stack Overflow
But this regex will consider non letters also à encoded as U+0061 U+0300 (if I understood well). For example using regex module in python the following snippet: Copyall_letter_doc = regex.sub(r'\P{L}', ' ', doc) ... Try ur'\P{L}' and replace with u' '. In case you want to replace all chars other ... More on stackoverflow.com
🌐 stackoverflow.com
python - How to replace all characters except letters, numbers, forward and back slashes - Stack Overflow
Want to parse through text and return only letters, digits, forward and back slashes and replace all else with ''. Is it possible to use just one regex pattern as opposed to several which then cal... More on stackoverflow.com
🌐 stackoverflow.com
April 25, 2017
string - Python - efficient method to remove all non-letters and replace them with underscores - Stack Overflow
The regex solution is incorrect since it replaces several adjacent non-letters as just one underscore. Drop the + after the character class and it will be correct albeit slower. More on stackoverflow.com
🌐 stackoverflow.com
January 31, 2010
🌐
Techie Delight
techiedelight.com › home › python › remove non-alphanumeric characters from a python string
Remove non-alphanumeric characters from a Python string | Techie Delight
3 weeks ago - The idea is to use the special character \W, which matches any character which is not a word character. ... The \W is equivalent of [^a-zA-Z0-9_], which excludes all numbers and letters along with underscores.
🌐
Delft Stack
delftstack.com › home › howto › python › remove non alphanumeric characters python
How to Remove Non-Alphanumeric Characters From Python String | Delft Stack
February 2, 2024 - We can use the sub() function from this module to replace all the string that matches a non-alphanumeric character with an empty character. The re.sub() function in Python is used to perform regular expression-based substitution in a string.
🌐
GeeksforGeeks
geeksforgeeks.org › python-remove-all-characters-except-letters-and-numbers
Remove All Characters Except Letters and Numbers - Python - GeeksforGeeks
April 19, 2025 - In this article, we’ll learn how ... will become "Geeksno1". Let’s explore different ways to achieve this in Python: re.sub() function replaces all characters that match a given pattern with a replacement....
Find elsewhere
🌐
Java2Blog
java2blog.com › home › python › remove non-alphanumeric characters in python
Remove Non-alphanumeric Characters in Python [3 Ways] - Java2Blog
November 10, 2023 - The \w (lowercase w) is used to match the word characters such as a digit, a letter, and an underscore ([a-zA-z0-9_]) while \W (uppercase W) is used to match the non-word characters which include anything excluding [a-zA-z0-9_].
🌐
Flexiple
flexiple.com › python › remove-non-alphanumeric-characters-python
Removing Non-Alphanumeric Characters in Python - Flexiple
March 21, 2024 - Regular expressions are particularly ... = re.sub(r'[^a-zA-Z0-9]', '', text) print(clean_text) ... The re.sub() function is used with the pattern [^a-zA-Z0-9], which matches any character that is not a letter or a numb...
Top answer
1 of 2
9

A fair bit faster and works for Unicode:

full_pattern = re.compile('[^a-zA-Z0-9\\\/]|_')

def re_replace(string):
    return re.sub(full_pattern, '', string)

If you want it really fast, this is by far the best (but slightly obscure) method:

def wanted(character):
    return character.isalnum() or character in '\\/'

ascii_characters = [chr(ordinal) for ordinal in range(128)]
ascii_code_point_filter = [c if wanted(c) else None for c in ascii_characters]

def fast_replace(string):
    # Remove all non-ASCII characters. Heavily optimised.
    string = string.encode('ascii', errors='ignore').decode('ascii')

    # Remove unwanted ASCII characters
    return string.translate(ascii_code_point_filter)

Timings:

SETUP="
busy = ''.join(chr(i) for i in range(512))

import re
full_pattern = re.compile('[^a-zA-Z0-9\\\/]|_')

def in_whitelist(character):
    return character.isalnum() or character in '\\/'

def re_replace(string):
    return re.sub(full_pattern, '', string)

def wanted(character):
    return character.isalnum() or character in '\\/'

ascii_characters = [chr(ordinal) for ordinal in range(128)]
ascii_code_point_filter = [c if wanted(c) else None for c in ascii_characters]

def fast_replace(string):
    string = string.encode('ascii', errors='ignore').decode('ascii')
    return string.translate(ascii_code_point_filter)
"

python -m timeit -s "$SETUP" "re_replace(busy)"
python -m timeit -s "$SETUP" "''.join(e for e in busy if in_whitelist(e))"
python -m timeit -s "$SETUP" "fast_replace(busy)"

Results:

10000 loops, best of 3: 63 usec per loop
10000 loops, best of 3: 135 usec per loop
100000 loops, best of 3: 4.98 usec per loop
2 of 2
4

Why can't you do something like:

def in_whitelist(character):
    return character.isalnum() or character in ['\\','/']

line2 = ''.join(e for e in line2 if in_whitelist(e))

Edited as per suggestion to condense function.

🌐
Python documentation
docs.python.org › 3 › library › re.html
re — Regular expression operations — Python 3.14.6 ...
May 25, 2026 - Source code: Lib/re/ This module provides regular expression matching operations similar to those found in Perl. Both patterns and strings to be searched can be Unicode strings ( str) as well as 8-...
🌐
Regex101
regex101.com › r › jI5hK6 › 1
regex101: Remove Non-Alphanumeric Characters
Online regex tester and debugger. Test, explain, benchmark, and generate code for PCRE2, JavaScript, Python, Go, Java, .NET, and Rust.
Top answer
1 of 5
20

The faster way to do it is to use str.translate() This is ~50 times faster than your way

# You only need to do this once
>>> title_trans=''.join(chr(c) if chr(c).isupper() or chr(c).islower() else '_' for c in range(256))

>>> "abcde1234!@%^".translate(title_trans)
'abcde________'

# Using map+lambda
$ python -m timeit '"".join(map(lambda x: x if (x.isupper() or x.islower()) else "_", "abcd1234!@#$".strip()))'
10000 loops, best of 3: 21.9 usec per loop

# Using str.translate
$ python -m timeit -s 'titletrans="".join(chr(c) if chr(c).isupper() or chr(c).islower() else "_" for c in range(256))' '"abcd1234!@#$".translate(titletrans)'
1000000 loops, best of 3: 0.422 usec per loop

# Here is regex for a comparison
$ python -m timeit -s 'import re;transre=re.compile("[\W\d]+")' 'transre.sub("_","abcd1234!@#$")'
100000 loops, best of 3: 3.17 usec per loop

Here is a version for unicode

# coding: UTF-8

def format_title_unicode_translate(title):
    return title.translate(title_unicode_trans)

class TitleUnicodeTranslate(dict):
    def __missing__(self,item):
        uni = unichr(item)
        res = u"_"
        if uni.isupper() or uni.islower():
            res = uni
        self[item] = res
        return res
title_unicode_trans=TitleUnicodeTranslate()

print format_title_unicode_translate(u"Metallica Μεταλλικα")

Note that the Greek letters count as upper and lower, so they are not substituted. If they are to be substituted, simply change the condition to

        if item<256 and (uni.isupper() or uni.islower()):
2 of 5
17
import re
title = re.sub("[\W\d]", "_", title.strip())

should be faster.

If you want to replace a succession of adjacent non-letters with a single underscore, use

title = re.sub("[\W\d]+", "_", title.strip())

instead which is even faster.

I just ran a time comparison:

C:\>python -m timeit -n 100 -s "data=open('test.txt').read().strip()" "''.join(map(lambda x: x if (x.isupper() or x.islower()) else '_', data))"
100 loops, best of 3: 4.51 msec per loop

C:\>python -m timeit -n 100 -s "import re; regex=re.compile('[\W\d]+'); data=open('test.txt').read().strip()" "title=regex.sub('_',data)"
100 loops, best of 3: 2.35 msec per loop

This will work on Unicode strings, too (under Python 3, \W matches any character which is not a Unicode word character. Under Python 2, you'd have to additionally set the UNICODE flag for this).

🌐
Reddit
reddit.com › r/learnpython › removing everything but letters, numbers, and spaces from string
r/learnpython on Reddit: Removing everything but letters, numbers, and spaces from string
May 18, 2019 -

So basically I have to remove all instances from a string that isn't a letter, number, or space... So far I'm able to remove everything that isn't a letter or space, however, I'm not sure how I would keep numbers for the way I did it.

Any help would be greatly appreciated. My code is as follows:

def remove_punctuation(word):
    
    new_word = ""
    
    for i in range(len(word)):

        for j in range(52):
            if word[i] == alpha[j]:
                new_word += alpha[j]

    return new_word
    
alpha = [' ', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C',
'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z']

print remove_punctuation("He$rs*hey {Bea%rs")

Obviously I can't add every number in the list, lol.

🌐
Reddit
reddit.com › r/learnprogramming › how can i remove all non alphabetic characters from my list of strings [python]
r/learnprogramming on Reddit: How can I remove all NON alphabetic characters from my list of strings [PYTHON]
March 11, 2015 -

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 listOfWords

Current Output

['lincoln’s', 'silly,', 'flat', 'dishwatery', 'utterances', 'chicago',    'times,', '1863']

Desired Output

["lincoln", "silly", "flat", "dishwatery", "utterances", "chicago", "times"]