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?


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

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.


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

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"


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


Merci! Notez que le @ dans quelque chose @ et '@here devraient également être supprimés, selon mes besoins.
fedorqui 'SO arrête de nuire'
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.