Legion
Legion

Reputation: 474

Python regex: insert spaces around characters and letters NOT surrounded by spaces

I have an expression 'Please calculate 1x20 +4 + 5-1 - 2/2 /4' which I need to convert to this:

'Please calculate 1 x 20 + 4 + 5 - 1 - 2 / 2 / 4' 

The important requirement being that there be only ONE space between the characters and letters of interest. I wrote the following code, which didn't work:

import re
message = 'Please calculate 1x20 +4 + 5-1 - 2/2 /4'
message = re.sub(r'\s*(?:(?<!\s)([<>x])(?!\s))\s*', " {0} ".format(re.search(r'\s*(?:(?<!\s)([<>x])(?!\s))\s*', message).group(0)), message)
message = re.sub(r'\s*(?:(?<!\s)([<>+])(?!\s))\s*', " {0} ".format(re.search(r'\s*(?:(?<!\s)([<>+])(?!\s))\s*', message).group(0)), message)
message = re.sub(r'\s*(?:(?<!\s)([<>-])(?!\s))\s*', " {0} ".format(re.search(r'\s*(?:(?<!\s)([<>-])(?!\s))\s*', message).group(0)), message)
message = re.sub(r'\s*(?:(?<!\s)([<>/])(?!\s))\s*', " {0} ".format(re.search(r'\s*(?:(?<!\s)([<>/])(?!\s))\s*', message).group(0)), message)
message = re.sub(r'\s*(?:(?<!\s)([<>*])(?!\s))\s*', " {0} ".format(re.search(r'\s*(?:(?<!\s)([<>*])(?!\s))\s*', message).group(0)), message)
print(message)

Where am I going wrong?

Upvotes: 1

Views: 37

Answers (2)

RomanPerekhrest
RomanPerekhrest

Reputation: 92854

Instead of using negative lookbehinds and redundantly repeating the same substitution you may just capture a potential surrounding whitespaces \s* (zero or more) and make an ensured replacement.

import re

message = 'Please calculate 1x20 +4 + 5-1 - 2/2 /4'
message = re.sub(r'\s*([<>x+*/-])\s*', ' \\1 ', message)
print(message)
  • \s* - zero or more occurrences of whitespace char
  • [<>x+*/-] - regex character class, to match only one out of several characters specified

The output:

Please calculate 1 x 20 + 4 + 5 - 1 - 2 / 2 / 4

Upvotes: 2

abdusco
abdusco

Reputation: 11091

Try capturing operators and surrounding them with spaces:

import re
if __name__ == '__main__':
    q = 'Please calculate 1x20 +4 + 5-1 - 2/2 /4'
    fixed = re.sub(r'\s*([+x/*\-])\s*', r' \1 ', q)
    print(fixed)

which prints:

Please calculate 1 x 20 + 4 + 5 - 1 - 2 / 2 / 4

Upvotes: 1

Related Questions