1

I need to surround ATK 30 (it is a variable, in fact, I have 5 variables) with spaces in the following text, in such a way that multiple spaces are avoided:

s = "Product desingATK 30Trace back. TheATK 30 is a nice device. "

The strings can have whitespace on either end or not, there may be letters, digits, anything.

I can replace spaces as follows:

s = s.replace("  ", " ")

But how can I surround my text with spaces?

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
Fluxy
  • 2,838
  • 6
  • 34
  • 63

1 Answers1

2

You can use

re.sub(r'\s*(ATK 30)\s*', r' \1 ', text)

See the regex demo.

Details

  • \s* - 0+ whitespaces
  • \b - a word boundary
  • (ATK 30) - Capturing group 1 (referred to with the \1 backreference from the replacement pattern): ATK 30
  • \s* - 0+ whitespaces

If you have a list of words and you need a dynamically built pattern use

import re
s = "Product desingATK 30Trace back. TheATK 30 is a nice device. "
keywords = ['ATK 30', 'PPK 50', 'HJF12 10']
pattern = fr'\s*({"|".join(sorted(map(re.escape, keywords),key=len,reverse=True))})\s*'
print(pattern)                       # => \s*(HJF12\ 10|ATK\ 30|PPK\ 50)\s*
print(re.sub(pattern, r' \1 ', s))  
# => Product desing ATK 30 Trace back. The ATK 30 is a nice device. 

Here, fr'\s*({"|".join(sorted(map(re.escape, keywords),key=len,reverse=True))})\s*' does the following:

  • map(re.escape, keywords) - escapes each keyword (so that ( or ? could not interfere with the task)
  • sorted(...,key=len,reverse=True) - sorts by length in descending order (the first alternative always "wins", so it is necessary)
  • "|".join(...) - creates the alternation pattern.
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563