3 votes

Python : remplacer les occurrences multiples d'un caractère par un mais les occurrences uniques par aucun.

J'ai une corde :

a = '0202201131181'

Je veux remplacer toutes les occurrences multiples de 1 sur a si elle est présente, par un seul 1 mais si une seule occurrence de '1' est trouvée, elle est remplacée par la chaîne vide ''.

Mon objectif final est d'obtenir :

a = '0202201318'

Ici, le '1' après le caractère '8' n'apparaît qu'une seule fois, il est donc remplacé par une chaîne vide, mais le '11' avant le caractère '3' et après le caractère '3' est remplacé par '1'.

Voici un bloc de code if-else que j'ai essayé, qui est partiellement correct :

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

Mais il produit '02022013181' ce qui est incorrect. Comment faire ?

10voto

iz_ Points 13277

Regex est probablement la meilleure option :

import re

a = '020220111311811001001001001'

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

Premier sub out single 1 puis soustraire les occurrences multiples de 1 . J'ai ajouté quelques caractères supplémentaires à a à des fins de test, et la sortie est

0202201318100000000

Si vous n'aimez pas la confusion causée par la phrase unique :

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

Explication de (?<!1)1(?=[^1]|$) :

  • (?<!1) : Assurez-vous que le caractère précédent n'est pas un 1 .
  • 1 : Correspondre littéralement à un 1 .
  • (?=[^1]|$) : Assurez-vous que le caractère à venir est soit a) pas un 1 ou b) est la fin de la chaîne.

1voto

Jay Points 8393

La solution basée sur Regex est la meilleure. Il n'y a pas deux avis sur ce point.

Une autre logique sans utiliser d'expressions régulières, juste pour mémoire :

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))

Sortie :

02022013181

0voto

Shivam Pandya Points 224

Il s'agit d'un moyen d'obtenir le résultat attendu sans utiliser de regex. Ce que je fais, c'est que je sépare la chaîne de '11' et que je remplace tous les '1' par des espaces vides et que je joins la liste à la chaîne avec '1' à nouveau.

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

Répartition de la compréhension de la liste :

a = '0202201131181'
tmp =[]

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

print(('1').join(tmp))

0voto

virolino Points 1780

Solution non-regex, inspirée par @Jay. Je n'ai aucune connaissance de Python, donc la syntaxe doit probablement être modifiée. Bien sûr, non testé. "Avantage" : les conditions sont moins compliquées (j'espère).

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))

0voto

Ora Aff Points 522
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)

J'ai essayé les quelques cas suivants avec le code ci-dessus :

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

NOTE : J'ai modifié mon code précédent.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X