Cleaning up an utterance using multiple regex substitutions I need to use regex for some stuff (mentioned in code comments) and wrote the following code, which works perfectly fine for my need, but I wanted to know if there was a way to improve this code?

Am I using re.compile correctly in this case?

import re

def regex(utterance):

    utterance = utterance.lower()

    # Replacing non ASCII characters with space
    message_ascii = re.compile(r'[^\x00-\x7F]+')
    message_ascii = message_ascii.sub(r' ', utterance)

    # If comma after number, replace comma with space
    message_comma_no = re.compile(r'(?&lt;=[0-9]),')
    message_comma_no = message_comma_no.sub(r' ',message_ascii)

    # If comma after words, add space before and after
    message_comma_word = re.compile(r'(?&lt;=[a-z]),')
    message_comma_word = message_comma_word.sub(r' , ',message_comma_no)

    # If "Dot and space" after word or number put space before and after
    message_dot = re.compile(r'(?&lt;=[a-z0-9])[.] ')
    message_dot = message_dot.sub(r' . ',message_comma_word)

    # If any other punctuation found after word or number put space before and after
    message_punct = re.compile(r"(?&lt;=[a-zA-Z0-9])(?=[?;!()'\"])|(?&lt;=[?;!()'\"])(?=[a-zA-Z0-9])")
    message_punct = message_punct.sub(r' ', message_dot)

    # Remove Excess whitespaces
    message = ' '.join(message_punct.split())

    return message
If you use a regular expression once, you don't get any performance improvement from compiling it. You could just use re.sub directly.
If a string doesn't contain any special characters, there's no point in using a raw literal.
r' ' could be just ' '.
Using the same variable to represent different things is a bad practice. It confuses the people who read your code. It's not a good idea to do things like:

message_ascii = re.compile(r'[^\x00-\x7F]+')
message_ascii = message_ascii.sub(r' ', utterance)


because the same variable holds a compiled regex in the first line and it's reassigned to a string later on.


If you call this function multiple times and want to benefit from pre-compiled regular expressions, you could create a new class that compiles the expressions in its constructor and reuses them:

class TextProcessor:

    def __init__(self):
        # Initializes regular expressions here
        self.ascii_regex = re.compile(...)
        # Other expressions go here

    def process_text(self, text):
        ascii_text = self.ascii_regex.sub(' ', text)
        # The rest of the substitions go here