Come posso sostituire la prima occorrenza di un personaggio in ogni parola?


44

Come posso sostituire la prima occorrenza di un personaggio in ogni parola?

Di 'che ho questa stringa:

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

E voglio rimuovere il primo @su ogni parola, in modo da finire con una stringa finale come questa:

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

Solo per chiarimenti, i caratteri "@" appaiono sempre insieme in ogni parola, ma possono essere all'inizio della parola o tra altri caratteri.

Sono riuscito a rimuovere il carattere "@" se si verifica solo una volta usando una variante della regex che ho trovato in Elimina sottostringa quando si verifica una volta, ma non quando due volte di seguito in Python , che utilizza un lookahead negativo e un lookbehind negativo:

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

Vedi l'output:

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

Quindi il prossimo passo è sostituire "@" quando si verifica più di una volta. Questo è facile facendo s.replace('@@', '@')rimuovere "@" da qualunque punto si verifichi.

Tuttavia, mi chiedo: c'è un modo per fare questa sostituzione in un colpo solo?


1
Hai bisogno di una risposta rigorosamente regex?
Sayandip Dutta,

@SayandipDutta in linea di principio, sì, ma sarei anche curioso di vedere altri modi per fare lo stesso senza regex :)
fedorqui 'COSÌ smetti di danneggiare' il

Giusto per essere sicuro, potrebbe esserci una stringa come: @Hello@Theredove @non sarebbe consecutiva?
JvdV

1
@JvdV no, non ci sarà un caso del genere.
fedorqui "SO smettere di danneggiare" il

Risposte:


51

Vorrei fare una sostituzione regex sul seguente schema:

@(@*)

E poi sostituiscilo con il primo gruppo di acquisizione, che è tutto continuo @ simboli, meno uno.

Questo dovrebbe catturare ogni @occorrenza all'inizio di ogni parola, sia quella parola all'inizio, a metà o alla fine della stringa.

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

Questo stampa:

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

35

Che ne dici di usare replace('@', '', 1)in un'espressione del generatore?

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"

Il valore int di 1è l' countargomento facoltativo .

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

Restituisce una copia della stringa con tutte le occorrenze della sottostringa vecchie sostituite da nuove . Se viene fornito il conteggio degli argomenti facoltativo , vengono sostituite solo le occorrenze del primo conteggio .


5
È un trucco intelligente! Poiché è il terzo parametro di sostituzione replace(search, replace, max_matches), sostituisce solo il primo su ogni parola.
fedorqui "SO smettere di danneggiare" il

1
@ fedorqui'SOstopharming 'sì, si chiama count, ho aggiunto la descrizione dai documenti.
Guy,

2
Fai attenzione a questo effetto collaterale: nel caso in cui tu abbia diversi spazi bianchi (''), verranno persi e sostituiti da un singolo ''.
Marc Vanhoomissen,

4

Puoi usare re.subcosì:

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)

Ciò comporterà:

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

Ed ecco una prova di concetto:

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

Stavo riflettendo sui casi che cosa succede se solo l'ultimo carattere è @e non vuoi rimuoverlo, o hai specifici caratteri iniziali consentiti, è venuto fuori con questo:

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

Oppure, supponi di voler sostituire @solo se è tra i primi n caratteri

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

Produzione:

inserisci qui la descrizione dell'immagine


Grazie! Si noti che anche @ in some @ cosa e '@here devono essere rimossi, secondo i miei requisiti.
Fedorqui "SO smettere di danneggiare" il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.