Python regex: How to increase only one number in string?

。_饼干妹妹 提交于 2021-02-05 07:52:06

问题


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?


回答1:


Ì 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




回答2:


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



回答3:


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


来源:https://stackoverflow.com/questions/55461769/python-regex-how-to-increase-only-one-number-in-string

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!