Regex code doesn’t match everything i want

Am new to regex, and spent hours trying to solve it but couldn’t, any help would be appreciated.

I have a text like this:

text = "(en termes de résultats et de qualité) sont difficiles à mesurer . L’accès aux prestations de santé du Medicare n’est pas soumis à conditions de ressources, et l’argent du contribuable finance son budget à hauteur de 3,6 %.text 4.text"

i am using this regex code : data = re.sub(r'(?<!d)s*([.,?:])s*', r'1 ', text)

to create a space after ‘.,,?:’ , but at the output i get something like that :

text = "(en termes de résultats et de qualité) sont difficiles à mesurer. L’accès aux prestations de santé du Medicare n’est pas soumis à conditions de ressources, et l’argent du contribuable finance son budget à hauteur de 3,6 %. text 4.text "

But when it comes to numbers at the end of the string it doesn’t create the space and that’s because of

the condition in regex, and am using it to not mess with other numbers like 3,6 it gonna turn it to
3, 6

and i don’t want that.

I want an output like that :

text = "(en termes de résultats et de qualité) sont difficiles à mesurer. L’accès aux prestations de santé du Medicare n’est pas soumis à conditions de ressources, et l’argent du contribuable finance son budget à hauteur de 3,6 %. text 4. text "

Also in some situations i have a text like that :

text = " 'L’accès aux prestations de santé du Medicare n’est pas soumis à conditions de ressources.' "

and want it to stay like that not adding the space after the dot

whenever i try to fix something the other thing blow it up.

Answer

You can use

 re.sub(r"s*(?!.')([.,?:])(?!(?<=d.)d)s*", r'1 ', text)

Regex details:

  • s* – zero or more whitespaces
  • (?!.') – a negative lookahead that fails the match if there is a .' char sequence immediately to the right of the current position
  • ([.,?:]) – a ., ,, ? or :
  • (?!(?<=d.)d) – a negative lookahead that fails the match if there is a digit (that is immediately preceded with a digit and any one char) immediately to the right of the current location
  • s* – zero or more whitespaces.

If you need to add more chars as “synonyms” to ', just use a character class. Here is an example with " and ':

 re.sub(r"""s*(?!.['"])([.,?:])(?!(?<=d.)d)s*""", r'1 ', text)