How to substitute a certain letter without substituting others?

Viewed 83

How to substitute a certain letter in a certain location without substituting the other same letter? For example:

text = `"I need help. I need 5.4 dollar."`

I tried:

a = re.compile('\D(\.)')
print(a.sub('\n',text))

However, the output was

"I need hel\n I need 5.4 dolla\n"

How can I get the output of

"I need help\n I need 5.4 dollar\n"
3 Answers

You can use a lookback:

>>> text = "I need help. I need 5.4 dollar."
>>> re.sub(r'(?<=\D)\.', '\n', text)
'I need help\n I need 5.4 dollar\n'

In this case (?<=\D) is asserting that the character in front of a literal . is not a digit.

Writing effective regular expressions starts with formulating what you need really specifically. In your case, it looks like you want to:

"Replace all periods with newline symbols, unless the period is part of a number."

And to make that even more precise, defining what it means that a period is part of a number: it likely means that it is followed directly by a number, so that it matches 5.4, but also .4 in The average score of .4 was low., but not 4. in She only counted a total of 4.

"Replace all periods with newline symbols, unless the period is followed immediately by a digit."

import re

text = '"I have .5 dollar. I need 5.4 dollar. But they only gave me 3."'

expression = re.compile(r'\.(?!\d)')
print(expression.sub('\n', text))

What your example \D(\.) matched instead was: "Match a single character that is not a digit, followed by a literal .", which is not what you wanted to replace.

The new expressions \.(?!\d) matches "Match a literal ., but only if it is not followed by a digit." It uses something called negative lookahead, more about that here https://www.regular-expressions.info/lookaround.html

For this particular example, you can use the regex metacharacter \b to match the beginning or end of a word (word boundary)

import re

text = "I need help. I need 5.4 dollar."

a = re.compile('\b(\.)')
print(a.sub('\n',text))
Related