idanshmu
idanshmu

Reputation: 5261

Using re.sub() to replace some part of a string

background

I'm trying to use re to replace some value in a string. Essentially, replace the first detected int (in a specific pattern) with 1.

Examples:

{1}        -> {1}
{2}        -> {1}
{3,}       -> {1,}
{3,16}     -> {1,16}
ab{3,16}   -> ab{1,16}
5a4b{3,16} -> 5a4b{1,16}
{1,4}      -> {1,4}

attempt

import re

pattern = '.*{(\d+)}|{(\d+),}|{(\d+),\d+}'
string = 'ab{3,16}'
print re.sub(pattern, '1', string)

But I get ab1 instead of ab{1,16}

Upvotes: 1

Views: 1113

Answers (3)

Udi
Udi

Reputation: 30482

If your pattern is always in the specified format (as in your examples), this will be enough:

print re.sub(r'{\d+', '{1', string, count=1)

Upvotes: 0

Eric Duminil
Eric Duminil

Reputation: 54223

You don't want to replace the {} or ,, so you could use positive lookaheads and lookbehinds in order to make sure the int is :

  • after a { with : (?<={)
  • before a } or a , with : (?=}|,)

If you want to want to replace only the first occurence in the whole string, you can set the 4th argument of sub to 1. In that case, {3}{3} will be converted to {1}{3}. UPDATE : You don't want it. :)

import re

pattern = '(?<={)\d+(?=}|,)'
string = 'ab{3,16}'
print re.sub(pattern, '1', string)

Here are some tests :

import re

def replace_first_int(string):
  pattern = '(?<={)\d+(?=}|,)'
  return re.sub(pattern, '1', string)

print replace_first_int('{1}')
# {1}
print replace_first_int('{2}')
# {1}
print replace_first_int('{3,}')
# {1,}
print replace_first_int('{3')
# {3
print replace_first_int('{3,16}')
# {1,16}
print replace_first_int('{1,4}')
# {1,4}
print replace_first_int('{3}{3}')
# {1}{1}
print replace_first_int('ab5')
# ab5
print replace_first_int('5a4b{3,16}')
# 5a4b{1,16}

Upvotes: 2

Sebastian Proske
Sebastian Proske

Reputation: 8413

When doing a replace with regex the whole matched string will be replaced. As you match the whole {1,16}, it is replaced by 1 accordingly.

For your samples (?<=\{)\d+ will work as pattern and can then replaced by 1, like

import re

pattern = '(?<={)\d+'
string = 'ab{3,16}'
print re.sub(pattern, '1', string)

Upvotes: 2

Related Questions