Python: Find and increment a number in a string

Question:

I can’t find a solution to this, so I’m asking here. I have a string that consists of several lines and in the string I want to increase exactly one number by one.
For example:

[CENTER]
[FONT=Courier New][COLOR=#00ffff][B][U][SIZE=4]{title}[/SIZE][/U][/B][/COLOR][/FONT]

[IMG]{cover}[/IMG]


[IMG]IMAGE[/IMG][/CENTER]
[QUOTE]
{description_de}
[/QUOTE]

[CENTER]



[IMG]IMAGE[/IMG]

[B]Duration: [/B]~5 min
[B]Genre: [/B]Action
[B]Subgenre: [/B]Mystery, Scifi
[B]Language: [/B]English
[B]Subtitles: [/B]German
[B]Episodes: [/B]01/5


[IMG]IMAGE[/IMG]
[spoiler]
[spoiler=720p]
[CODE=rich][color=Turquoise]
{mediaInfo1}
[/color][/code]
[/spoiler]
[spoiler=1080p]
[CODE=rich][color=Turquoise]
{mediaInfo2}
[/color][/code]
[/spoiler]
[/spoiler]



[hide]
[IMG]IMAGE[/IMG]
[/hide]
[/CENTER]

I’m getting this string from a request and I want to increment the episode by 1. So from 01/5 to 02/5.

What is the best way to make this possible?

I tried to solve this via regex but failed miserably.

Asked By: kiddo

||

Answers:

Assuming the number you want to change is always after a given pattern, e.g. "Episodes: [/B]", you can use this code:

def increment_episode_num(request_string, episode_pattern="Episodes: [/B]"):
    idx = req_str.find(episode_pattern) + len(episode_pattern)
    episode_count = int(request_string[idx:idx+2])
    return request_string[:idx]+f"{(episode_count+1):0>2}"+request_string[idx+2:]

For example, given your string:


req_str = """[B]Duration: [/B]~5 min
            [B]Genre: [/B]Action
            [B]Subgenre: [/B]Mystery, Scifi
            [B]Language: [/B]English
            [B]Subtitles: [/B]German
            [B]Episodes: [/B]01/5
            """

res = increment_episode_num(req_str)
print(res)

which gives you the desired output:

[B]Duration: [/B]~5 min
[B]Genre: [/B]Action
[B]Subgenre: [/B]Mystery, Scifi
[B]Language: [/B]English
[B]Subtitles: [/B]German
[B]Episodes: [/B]02/5
Answered By: Luca Clissa

As @Barmar suggested in Comments, and following the example from the documentation of re, also formatting to have the right amount of zeroes as padding:

pattern = r"(?<=Episodes: [/B])[d]+?(?=/d)"

def add_one(matchobj):
    number = str(int(matchobj.group(0)) + 1)
    return "{0:0>2}".format(number)

re.sub(pattern, add_one, request)

The pattern uses look-ahead and look-behind to capture only the number that corresponds to Episodes, and should work whether it’s in the format 01/5 or 1/5, but always returns in the format 01/5. Of course, you can expand the function so it recognizes the format, or even so it can add different numbers instead of only 1.

Answered By: Ignatius Reilly
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.