Python: заменить многократное вхождение персонажа одним, но одно вхождение ни одним - PullRequest
0 голосов
/ 04 февраля 2019

У меня есть строка:

a = '0202201131181'

Я хочу заменить все множественные вхождения 1 в a, если они присутствуют, на один 1, но если только одно вхождение '1'найден, затем замените его пустой строкой ''.

Моя конечная цель - получить:

a = '0202201318'

Здесь '1' после символа '8' встречается только один раз, поэтомузаменяется пустой строкой, но «11» перед символом «3» и после символа «3» заменяется на «1».

Вот код блока if-else, который я пробовал,частично верно:

if '11' in a:
    a = a.replace("11","1")
else:
    a = a.replace("1","")

Но выводит '02022013181', что неверно.Как это сделать?

Ответы [ 5 ]

0 голосов
/ 04 февраля 2019
a = '111020220113111111'
while a.find('11') != -1:
  i = 0
  j = 1
  while i < len(a):
    for c in a:
        if a[i] == '1':
            if a[j] == '1':
                a = a.replace(a[i],'x')
    i = i + 1
    j = i + 1
  a = a.replace("xx","1")
  a = a.replace("x","1")
print(a)

Я пробовал следующие несколько случаев с приведенным выше кодом:

a = '111020220113111111'          >> 1020220131
a = '020220111311811001001001001' >> 02022013181001001001001
a = '0202201131181'               >> 02022013181

ПРИМЕЧАНИЕ: отредактировал мой предыдущий код.

0 голосов
/ 04 февраля 2019

Решение без регулярных выражений, вдохновленное @Jay.У меня нулевое знание Python, поэтому синтаксис, вероятно, нуждается в изменении.Конечно, не проверено.«Выгода»: условия менее сложны (надеюсь).

a = '110202201111311811'
new_str = []

while (not end of string) :
    while ((a[i]!='1') and (not end of string))
        new_str.append(a[i])
        i++

    if (a[i+1] is not out of range ) and (a[i+1] != '1') :
        i++
    else :
        new_str.append(a[i])
        while a[i]=='1' :
            i++

print ("".join(x for x in new_str))
0 голосов
/ 04 февраля 2019

Это способ достижения ожидаемого результата без использования регулярных выражений.Что я делаю, так это то, что я разделяю строку из '11' и заменяю все '1' пустым пространством и снова соединяю список в строку с '1'.

a = '0202201131181'
tmp =[ i.replace('1', '') for i in a.split('11')]
print(('1').join(tmp))

Разбивка понимания списка:

a = '0202201131181'
tmp =[]

for i in a.split('11'):
  i = i.replace('1','')
  tmp.append(i)

print(('1').join(tmp))
0 голосов
/ 04 февраля 2019

Решение на основе регулярных выражений является лучшим.Нет двух мыслей по этому поводу.

Просто еще одна логика без использования регулярных выражений, просто для записи:

a = '110202201111311811'
new_str = []

for i in range(len(a)):
   if a[i] == '1':
       if (i!= (len(a)-1) and a[i+1] == '1') and (i!=0 and a[i-1] != '1'):
           new_str.append(a[i])
   else:
       new_str.append(a[i])

print ("".join(x for x in new_str))

Вывод:

02022013181
0 голосов
/ 04 февраля 2019

Regex, вероятно, лучший вариант:

import re

a = '020220111311811001001001001'

a = re.sub(r'1{2,}', '1', re.sub(r'(?<!1)1(?=[^1]|$)', '', a))
print(a)

Сначала подпишите один 1 с, затем подпишите несколько вхождений 1.Я добавил еще несколько символов в a для целей тестирования, и вывел:

0202201318100000000

Если вам не нравится некоторая путаница, вызванная однострочным:

a = re.sub(r'(?<!1)1(?=[^1]|$)', '', a)
a = re.sub(r'1{2,}', '1', a)

Объяснение (?<!1)1(?=[^1]|$):

  • (?<!1): убедитесь, что указанный ранее символ не является 1.
  • 1: буквально соответствует 1.
  • (?=[^1]|$): убедитесь, что символ впереди - либо а), а не 1, либо б) конец строки.
...