Wie kann ich das erste Vorkommen eines Zeichens in jedem Wort ersetzen?

44

Wie kann ich das erste Vorkommen eines Zeichens in jedem Wort ersetzen?

Angenommen, ich habe diese Zeichenfolge:

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

Und ich möchte das erste @bei jedem Wort entfernen , damit ich am Ende eine letzte Zeichenfolge wie diese habe:

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

Nur zur Verdeutlichung werden "@" -Zeichen in jedem Wort immer zusammen angezeigt, können sich jedoch am Wortanfang oder zwischen anderen Zeichen befinden.

Ich habe es geschafft, das "@" -Zeichen zu entfernen, wenn es nur einmal vorkommt, indem ich eine Variation des regulären Ausdrucks verwendet habe, den ich in " Teilzeichenfolge löschen" gefunden habe, wenn es einmal vorkommt, aber nicht, wenn es in Python zweimal hintereinander vorkommt , wobei ein negativer Lookahead und ein negativer Lookbehind verwendet werden:

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

Siehe die Ausgabe:

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

Der nächste Schritt besteht also darin, das "@" zu ersetzen, wenn es mehr als einmal auftritt. Dies ist einfach, indem Sie s.replace('@@', '@')das "@" von der Stelle entfernen, an der es erneut auftritt.

Ich frage mich jedoch: Gibt es eine Möglichkeit, diesen Ersatz auf einmal durchzuführen?

fedorqui 'SO hör auf zu schaden'
quelle
1
Benötigen Sie eine streng reguläre Antwort?
Sayandip Dutta
@ SayandipDutta im Prinzip, ja, aber ich wäre auch neugierig, andere Möglichkeiten zu sehen, um dasselbe ohne Regex zu tun :)
fedorqui 'SO hör auf zu schaden'
Nur um sicherzugehen, könnte es eine Zeichenfolge geben wie: @Hello@ThereWo @wäre nicht aufeinanderfolgend?
JvdV
1
@JvdV nein, es wird keinen solchen Fall geben.
Fedorqui 'SO hör auf zu schaden'

Antworten:

51

Ich würde einen Regex-Ersatz nach folgendem Muster durchführen:

@(@*)

Und dann ersetzen Sie einfach durch die erste Erfassungsgruppe, die alle fortlaufenden @ -Symbole minus eins enthält.

Dies sollte jedes @am Anfang jedes Wortes vorkommende Wort erfassen , sei es das Wort am Anfang, in der Mitte oder am Ende der Zeichenfolge.

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

Dies druckt:

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

Wie wäre es mit der Verwendung replace('@', '', 1)in einem Generatorausdruck?

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"

Der int-Wert von 1ist das optionale countArgument.

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

Geben Sie eine Kopie der Zeichenfolge zurück, wobei alle Vorkommen von alten Teilzeichenfolgen durch neue ersetzt werden . Wenn die optionale Argument Zahl angegeben wird, werden nur die erste Zählung sind Vorkommen ersetzt.

Kerl
quelle
5
Das ist ein kluger Trick! Da der dritte Parameter von replace ist replace(search, replace, max_matches), ersetzt er nur den ersten bei jedem Wort.
Fedorqui 'SO hör auf zu schaden'
1
@ fedorqui'SOstopharming 'ja, es heißt count, ich habe die Beschreibung aus den Dokumenten hinzugefügt.
Guy
2
Achten Sie auf diesen Nebeneffekt: Wenn Sie mehrere Leerzeichen ('') haben, gehen diese verloren und werden durch ein einzelnes '' ersetzt.
Marc Vanhoomissen
4

Sie können re.subwie folgt verwenden:

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)

Das führt zu:

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

Und hier ist ein Proof of 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
quelle
2

Ich habe über Fälle nachgedacht, was passiert, wenn nur das letzte Zeichen vorhanden ist @und Sie es nicht entfernen möchten oder wenn Sie bestimmte zulässige Startzeichen haben:

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

Oder nehmen wir an, Sie möchten @nur ersetzen , wenn es sich um die ersten n Zeichen handelt

>>> ' '.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
quelle
2

DEMO

(?<!@)@

Sie können dies versuchen. Siehe Demo.

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

Ausgabe:

Geben Sie hier die Bildbeschreibung ein

Amar Kumar
quelle
Vielen Dank! Beachten Sie, dass das @ in einem @ -Ding und '@here' gemäß meinen Anforderungen ebenfalls entfernt werden sollte.
fedorqui 'SO hör auf zu schaden'