8
votes

Comment fusionner une séquence de caractères identiques en un seul?

Supposons que j'ai ceci:

My --- Sun - est ------ très gros ---.

Je veux remplacer tous les deux traits d'union avec un seul trait d'union.


1 commentaires

Voulez-vous vraiment coalcer uniquement des traits d'union, ou une série de caractères en double?


10 Réponses :


18
votes
import re

astr='My---sun--is------very-big---.'

print(re.sub('-+','-',astr))
# My-sun-is-very-big-.

1 commentaires

+1, mais - {2,} éviterait de remplacer un seul - inutilement.



1
votes
re.sub('-+', '-', "My---sun--is------very-big---")

0 commentaires

2
votes

Que diriez-vous:

>>> import re
>>> re.sub("-+", "-", "My---sun--is------very-big---.")
'My-sun-is-very-big-.'


0 commentaires

5
votes

Si vous voulez vraiment seulement fusionner des traits d'union, utilisez les autres suggestions. Sinon, vous pouvez écrire votre propre fonction, comme ceci:

>>> def coalesce(x):
...     n = []
...     for c in x:
...         if not n or c != n[-1]:
...             n.append(c)
...     return ''.join(n)
...
>>> coalesce('My---sun--is------very-big---.')
'My-sun-is-very-big-.'
>>> coalesce('aaabbbccc')
'abc'


2 commentaires

+1 pour une solution générale. Étant donné que l'OP a utilisé des mots anglais dans leur exemple, la spécification d'un ensemble de caractères à coalesce (ou non de regroupement) serait probablement préférable de manière à éviter des mots de mangling à deux lettres (c'est-à-dire des lettres).


Convenu sur le +1 pour une solution générale



5
votes

Comme d'habitude, il y a une solution iTertools , à l'aide de groupby : xxx


2 commentaires

Cette solution ne répond pas à la question si vous voulez seulement déduire les traits d'union. Y a-t-il une solution iTertools qui garderait «AAAAA»?


@Mcpeterson: Bien sûr, mais ils ne sont pas aussi gentils. Pour simplement gérer des traits d'union, vous pouvez faire ''. Joindre (clé si toule == '- «Autres» .join (groupe) pour la clé, groupe en groupeby (s)) . Pour manipuler tout caractère non alphanumérique, ''. Joindre ('. Joindre (groupe) si clé.isalnum () Sinon Touche pour la clé, groupe en groupeby (s)) . Mais j'utiliserais plutôt l'une des solutions de regex à la place.



13
votes

Si vous souhaitez remplacer tout em> exécution de caractères consécutifs, vous pouvez utiliser

>>> print(re.sub(r"(\W)\1+",r"\1",a))
AA-BC+DDDD-EE$FF


0 commentaires

1
votes

Que diriez-vous d'une alternative sans le module RE:

def coalesce_factory(x):
    return lambda sent: x.join(filter(lambda w: len(w) > 0, sent.split(x)))

hyphen_coalesce = coalesce_factory("-")
hyphen_coalesce('My---sun--is------very-big---.')


0 commentaires

0
votes

Une autre solution simple est la fonction de remplacement de l'objet de chaîne.

while '--' in astr:
    astr = astr.replace('--','-')


1 commentaires

Cela sera très inefficace en cas de texte important.



0
votes

Si vous ne voulez pas utiliser des expressions régulières:

    my_string = my_string.split('-')
    my_string = filter(None, my_string)
    my_string = '-'.join(my_string)


0 commentaires

0
votes

J'ai xxx

je veux xxx

compresser toutes les ébauches (le "remplacer"), puis diviser sur la virgule , alors sinon personne ne rejoint avec une virgule entre: xxx


0 commentaires