1

I have a string of following types:

a1 = 'images1subimages1/folder100/hello1.png'
a1 = 'images1subimages1 folder100 hello1.png'
a1 = 'images1subimages1folder100hello1.png'
a1 = 'images1b100d1.png'

The first Integer of the string is num0 and we only care about it. We want to increase all occurrence of num0 by one and keep other numbers the same.

Required:

a2 = 'images2subimages2/folder100/hello2.png'
a2 = 'images2subimages2 folder100 hello2.png'
a2 = 'images2subimages2folder100hello2.png'
a2 = 'images2b100d2.png'

My attempt:

import re
a1 = 'images1subimages1/folder100/hello1.png'

nums = list(map(int, re.findall(r'\d+', a1)))
nums0 = nums[0]
nums_changed = [j+1  if j==nums[0] else j for i,j in enumerate(nums)]
parts = re.findall(r'(\w*\d+)',a1)
for i in range(len(parts)):
  num_parts = list(map(int, re.findall(r'\d+', parts[i])))
  for num_part in num_parts:
    if num_part == nums0:
        parts[i] = parts[i].replace(str(nums0), str(nums0+1))


ans = '/'.join(parts)
ans

This has the following result:

a1 = 'images1subimages1/folder100/hello1.png' # good
a1 = 'images1subimages1 folder100 hello1.png' # bad

Is there a general way to solve the problem using regex in python?

3 Answers 3

3

Ì suggest first extracting the first number and then increment all occurrences of this number when it is not enclosed with other digits with re.sub:

import re
a1 = 'images1subimages1/folder100/hello1.png'
num0_m = re.search(r'\d+', a1)                  # Extract the first chunk of 1+ digits
if num0_m:                                      # If there is a match
    rx = r'(?<!\d){}(?!\d)'.format(num0_m.group())  # Set a regex to match the number when not inside other digits
    print(re.sub(rx, lambda x: str(int(x.group())+1), a1)) # Increment the matched numbers
    # => images2subimages2/folder100/hello2.png

See the Python demo

Sign up to request clarification or add additional context in comments.

Comments

1

You can split the string on numbers, increment the ones equal to the first one, and rebuild the string:

import re


def increment_first(s):
    parts = re.split(r'(\d+)', s)
    nums = list(map(int, parts[1::2]))
    num0 = nums[0]
    nums = [num + (num == num0) for num in nums]
    parts[1::2] = map(str, nums)
    return ''.join(parts)

Testing it on your data:

tests = ['images1subimages1/folder100/hello1.png',
'images1subimages1 folder100 hello1.png',
'images1subimages1folder100hello1.png',
'images1b100d1.png']

for test in tests:
    print(test, increment_first(test))

Output:

images1subimages1/folder100/hello1.png images2subimages2/folder100/hello2.png
images1subimages1 folder100 hello1.png images2subimages2 folder100 hello2.png
images1subimages1folder100hello1.png images2subimages2folder100hello2.png
images1b100d1.png images2b100d2.png

Comments

1

Alas, I'm not as fast as some of these regex gurus. Here is my solution anyway.

  1. Find the first occurrence of a number re.search(r'\d+', st).group(0)
  2. Substitute the first occurrence where the found number is not preceded or followed by another number (?<!\d)+' + re.escape(first) + r'(?!\d)+.
import re


def increment_all_of_first_occurring_number(st):
    first = re.search(r'\d+', st).group(0)
    return re.sub(
        r'(?<!\d)+' + re.escape(first) + r'(?!\d)+',
        str(int(first) + 1),
        st
    )


if __name__ == '__main__':
    a1 = 'images1subimages1/folder100/hello1.png'
    a2 = 'images1subimages1 folder100 hello1.png'
    a3 = 'images1subimages1folder100hello1.png'
    a4 = 'images1b100d1.png'

    b1 = 'images10subimages10/folder10101/hello10.png'
    b2 = 'images10subimages10 folder10101 hello10.png'
    b3 = 'images10subimages10folder10101hello10.png'
    b4 = 'images10b10101d10.png'

    print(increment_all_of_first_occurring_number(a1))
    print(increment_all_of_first_occurring_number(a2))
    print(increment_all_of_first_occurring_number(a3))
    print(increment_all_of_first_occurring_number(a4))

    print(increment_all_of_first_occurring_number(b1))
    print(increment_all_of_first_occurring_number(b2))
    print(increment_all_of_first_occurring_number(b3))
    print(increment_all_of_first_occurring_number(b4))

Results

images2subimages2/folder100/hello2.png
images2subimages2 folder100 hello2.png
images2subimages2folder100hello2.png
images2b100d2.png
images11subimages11/folder10101/hello11.png
images11subimages11 folder10101 hello11.png
images11subimages11folder10101hello11.png
images11b10101d11.png

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.