Comment remplacer la première occurrence d'un caractère dans chaque mot?

44

Comment remplacer la première occurrence d'un caractère dans chaque mot?

Disons que j'ai cette chaîne:

hello @jon i am @@here or @@@there and want some@thing in '@here"
#     ^         ^^        ^^^                   ^          ^ 

Et je veux supprimer le premier @de chaque mot, pour finir par avoir une chaîne finale comme celle-ci:

hello jon i am @here or @@there and want something in 'here
#     ^        ^        ^^                   ^         ^

Pour plus de précision, les caractères "@" apparaissent toujours ensemble dans chaque mot, mais peuvent être au début du mot ou entre d'autres caractères.

J'ai réussi à supprimer le caractère "@" s'il se produit une seule fois en utilisant une variation de l'expression régulière que j'ai trouvée dans la sous-chaîne Supprimer quand il se produit une fois, mais pas deux fois de suite en python , qui utilise un lookahead négatif et un lookbehind négatif:

@(?!@)(?<!@@)

Voir la sortie:

>>> s = "hello @jon i am @@here or @@@there and want some@thing in '@here"
>>> re.sub(r'@(?!@)(?<!@@)', '', s)
"hello jon i am @@here or @@@there and want something in 'here"

La prochaine étape consiste donc à remplacer le "@" lorsqu'il se produit plusieurs fois. Ceci est facile en s.replace('@@', '@')supprimant le "@" partout où il se reproduit.

Cependant, je me demande: existe-t-il un moyen de faire ce remplacement en une seule fois?

fedorqui 'SO arrête de nuire'
la source
1
Avez-vous besoin d'une réponse strictement regex?
Sayandip Dutta
@SayandipDutta en principe, oui, mais je serais également curieux de voir d'autres façons de faire la même chose sans regex :)
fedorqui 'SO stop harming'
Juste pour être sûr, pourrait-il y avoir une chaîne comme: @Hello@There@ne serait pas consécutive?
JvdV
1
@JvdV non, il n'y aura pas un tel cas.
fedorqui 'SO arrête de nuire' le

Réponses:

51

Je ferais un remplacement regex sur le modèle suivant:

@(@*)

Et puis remplacez simplement par le premier groupe de capture, qui est tous des symboles @ continus, moins un.

Cela devrait capturer chaque @occurrence au début de chaque mot, que ce soit au début, au milieu ou à la fin de la chaîne.

inp = "hello @jon i am @@here or @@@there and want some@thing in '@here"
out = re.sub(r"@(@*)", '\\1', inp)
print(out)

Cela imprime:

hello jon i am @here or @@there and want something in 'here
Tim Biegeleisen
la source
35

Que diriez-vous d'utiliser replace('@', '', 1)dans une expression de générateur?

string = 'hello @jon i am @@here or @@@there and want some@thing in "@here"'
result = ' '.join(s.replace('@', '', 1) for s in string.split(' '))

# output: hello jon i am @here or @@there and want something in "here"

La valeur int de 1est l' countargument facultatif .

str.replace(old, new[, count])

Renvoie une copie de la chaîne avec toutes les occurrences de la sous-chaîne old remplacée par new . Si le nombre d' arguments facultatif est donné, seules les premières occurrences de comptage sont remplacées.

Gars
la source
5
Voilà une astuce astucieuse! Puisque le troisième paramètre de replace est replace(search, replace, max_matches), il remplace simplement le premier sur chaque mot.
fedorqui 'SO arrête de nuire' le
1
@ fedorqui'SOstopharming 'oui, ça s'appelle count, j'ai ajouté la description des docs.
Guy
2
Attention à cet effet secondaire: si vous avez plusieurs espaces blancs (''), ils seront perdus et remplacés par un seul ''.
Marc Vanhoomissen
4

Vous pouvez utiliser re.subcomme ceci:

import re

s = "hello @jon i am @@here or @@@there and want some@thing in '@here"
s = re.sub('@(\w)', r'\1', s)
print(s)

Cela se traduira par:

"hello jon i am @here or @@there and want something in 'here"

Et voici une preuve de concept:

>>> import re
>>> s = "hello @jon i am @@here or @@@there and want some@thing in '@here"
>>> re.sub('@(\w)', r'\1', s)
"hello jon i am @here or @@there and want something in 'here"
>>> 
accdias
la source
2

Était en train de réfléchir aux cas si seulement le dernier caractère était @et que vous ne vouliez pas le supprimer, ou si vous aviez des caractères de démarrage autorisés spécifiques, est venu avec ceci:

>>> ' '.join([s_.replace('@', '', 1) if s_[0] in ["'", "@"] else s_ for s_ in s.split()])
"hello jon i am @here or @@there and want some@thing in 'here"

Ou, supposons que vous ne souhaitiez remplacer @que s'il est composé des n premiers caractères

>>> ' '.join([s_.replace('@', '', 1) if s_.find('@') in range(2) else s_ for s_ in s.split()])
"hello jon i am @here or @@there and want some@thing in 'here"
Sayandip Dutta
la source
2

DEMO

(?<!@)@

Vous pouvez essayer ça. Voir la démo.

vks
la source
1
# Python3 program to remove the @ from String


def ExceptAtTheRate(string):
    # Split the String based on the space
    arrOfStr = string.split()

    # String to store the resultant String
    res = ""

    # Traverse the words and
    # remove the first @ From every word.
    for a in arrOfStr:
        if(a[0]=='@'):
            res += a[1:len(a)] + " "
        else:
            res += a[0:len(a)] + " "

    return res


# Driver code
string = "hello @jon i am @@here or @@@there and want some@thing in '@here"

print(ExceptAtTheRate(string))

Production:

entrez la description de l'image ici

Amar Kumar
la source
Merci! Notez que le @ dans quelque chose @ et '@here devraient également être supprimés, selon mes besoins.
fedorqui 'SO arrête de nuire'