Reputation: 461
I have a string as such testing_7_3_4_testing
i want to replace testing_7_3_4_testing
with testing_7.3.4_testing
, i have tried using str.replace(/\d_\d/, ".")
and im getting some really weird results. Regex experts please help!
Upvotes: 2
Views: 446
Reputation: 48599
Try this:
import re
my_strs = [
'testing_7_3_4_testing',
'testing_7_3_testing',
'testing_7_3_4_5',
'testing_71_312_4123_testing',
]
pattern = r"""
(\d+) #Match a digit, one or more times, captured in group 1, followed by...
_ #an underscore, followed by...
(?=\d+) #a digit, one or more times, but do not include as part of the match
"""
for my_str in my_strs:
new_str = re.sub(pattern, r'\1.', my_str, flags=re.X)
print(new_str)
--output:--
testing_7.3.4_testing
testing_7.3_testing
testing_7.3.4.5
testing_71.312.4123_testing
The pattern (?=\d+)
says to match a digit, one or more times, but do not actually include the matching digits as part of the match.
Upvotes: 4
Reputation: 473813
Save each digit into it's own saving group, reference the groups in your replacement string:
>>> import re
>>> s = "testing_7_3_4_testing"
>>> re.sub(r"(\d)_(\d)_(\d)", r"\1.\2.\3", s)
'testing_7.3.4_testing'
Or, we can make use of a replacement function, which, in contrast to the first approach, also handles variable number of digits in the input string:
>>> def replacement(m):
... x, y, z = m.groups()
... return x + y.replace("_", ".") + z
...
>>> re.sub(r"(.*?_)([0-9_]+)(_.*?)", replacement, s)
'testing_7.3.4_testing'
A non-regex approach would involve splitting by _
, slicing and joining:
>>> l = s.split("_")
>>> l[0] + "_" + ".".join(l[1:-1]) + "_" + l[-1]
'testing_7.3.4_testing'
Upvotes: 2