Регулярное выражение Python: Как увеличить только одно число в строке? - PullRequest
1 голос
/ 01 апреля 2019

У меня есть строка следующих типов:

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

Первое целое число строки - num0, и мы заботимся только о нем. Мы хотим увеличить все вхождения num0 на один, а остальные числа оставить прежними.

Обязательно:

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

Моя попытка:

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

Это имеет следующий результат:

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

Есть ли общий способ решения проблемы с помощью регулярных выражений в python?

Ответы [ 3 ]

2 голосов
/ 01 апреля 2019

Ì предлагает сначала извлечь первое число, а затем увеличить все вхождения этого числа, если оно не заключено в другие цифры, с помощью 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

См. Демоверсию Python

1 голос
/ 01 апреля 2019

Увы, я не так быстр, как некоторые из этих регулярных гуру. В любом случае, вот мое решение.

  1. Найти первое вхождение числа re.search(r'\d+', st).group(0)
  2. Заменить первое вхождение, где найденному номеру не предшествует или не следовать другое число (?<!\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))

Результаты

images2subimages2/folder100/hello2.png
images2subimages2 folder100 hello2.png
images2subimages2folder100hello2.png
images2b100d2.png
images11subimages11/folder10101/hello11.png
images11subimages11 folder10101 hello11.png
images11subimages11folder10101hello11.png
images11b10101d11.png
1 голос
/ 01 апреля 2019

Вы можете разбить строку на числа, увеличить значения, равные первому, и перестроить строку:

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)

Тестирование на ваших данных:

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

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

Выход:

images1subimages1/folder100/hello1.png images2subimages2/folder100/hello2.png
images1subimages1 folder100 hello1.png images2subimages2 folder100 hello2.png
images1subimages1folder100hello1.png images2subimages2folder100hello2.png
images1b100d1.png images2b100d2.png
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...