web-dev-qa-db-de.com

Entfernen Sie bestimmte Zeichen aus einer Zeichenfolge in Python

Ich versuche, bestimmte Zeichen mit Python aus einer Zeichenfolge zu entfernen. Dies ist der Code, den ich gerade verwende. Leider scheint es nichts mit dem String zu tun.

for char in line:
    if char in " ?.!/;:":
        line.replace(char,'')

Wie mache ich das richtig?

415
Matt Phillips

Zeichenfolgen in Python sind immutable (können nicht geändert werden). Aus diesem Grund besteht der Effekt von line.replace(...) darin, eine neue Zeichenfolge zu erstellen, anstatt die alte zu ändern. Sie müssen rebind (zuweisen) und line zuweisen, damit diese Variable den neuen Wert übernimmt und diese Zeichen entfernt werden.

Die Art und Weise, wie Sie es tun, wird relativ langsam sein. Für erfahrene Pythonisten ist es wahrscheinlich etwas verwirrend, da sie eine doppelt geschachtelte Struktur sehen und für einen Moment denken, dass etwas komplizierteres vor sich geht.

Ab Python 2.6 und neueren Python 2.x-Versionen * können Sie stattdessen str.translate , verwenden (lesen Sie jedoch die Unterschiede zu Python 3):

line = line.translate(None, '[email protected]#$')

oder Ersetzen von regulären Ausdrücken durch re.sub

import re
line = re.sub('[[email protected]#$]', '', line)

Die in Klammern eingeschlossenen Zeichen bilden eine Zeichenklasse. Alle Zeichen in line, die sich in dieser Klasse befinden, werden durch den zweiten Parameter in sub ersetzt: eine leere Zeichenfolge.

In Python 3 sind Zeichenfolgen Unicode. Sie müssen etwas anders übersetzen. kevpie erwähnt dies in einem Kommentar zu einer der Antworten, und es wird in der Dokumentation für str.translate vermerkt.

Wenn Sie die translate-Methode einer Unicode-Zeichenfolge aufrufen, können Sie den zweiten Parameter, den wir oben verwendet haben, nicht übergeben. Sie können auch None nicht als ersten Parameter oder gar eine Übersetzungstabelle von string.maketrans übergeben. Stattdessen übergeben Sie ein Wörterbuch als einzigen Parameter. Dieses Wörterbuch ordnet die ordinal-Werte von Zeichen (dh das Ergebnis des Aufrufs von ord auf sie) den ordinalen Werten der Zeichen zu, die sie ersetzen sollen, oder - nützlich für uns --None, um anzuzeigen, dass sie dies sollten gelöscht werden.

Um den oben genannten Tanz mit einer Unicode-Zeichenfolge auszuführen, würden Sie so etwas nennen

translation_table = dict.fromkeys(map(ord, '[email protected]#$'), None)
unicode_line = unicode_line.translate(translation_table)

Hier werden dict.fromkeys und map verwendet, um prägnant ein Wörterbuch mit zu erzeugen

{ord('!'): None, ord('@'): None, ...}

Noch einfacher, als eine andere Antwort gibt es , erstellen Sie das Wörterbuch:

unicode_line = unicode_line.translate({ord(c): None for c in '[email protected]#$'})

* Zur Kompatibilität mit früheren Pythons können Sie eine "Null" -Übersetzungstabelle erstellen, die anstelle von None übergeben wird:

import string
line = line.translate(string.maketrans('', ''), '[email protected]#$')

Hier wird mit string.maketrans eine translation-Tabelle erstellt. Hierbei handelt es sich lediglich um eine Zeichenfolge, die die Zeichen mit den Ordinalwerten 0 bis 255 enthält.

528
intuited

Verpasse ich den Punkt hier oder ist es nur Folgendes:

>>> string = "ab1cd1ef"
>>> string.replace("1","")
'abcdef'
>>>

Setze es in eine Schleife:

>>>
>>> a = "[email protected]#d$"
>>> b = "[email protected]#$"
>>> for char in b:
...     a = a.replace(char,"")
...
>>> print a
abcd
>>>
180
gsbabil
>>> line = "abc#@!?efg12;:?"
>>> ''.join( c for c in line if  c not in '?:!/;' )
'abc#@efg12'
37
ghostdog74

Einfach mit re.sub in Python 3.5

re.sub('\ |\?|\.|\!|\/|\;|\:', '', line)

Beispiel

>>> import re

>>> line = 'Q: Do I write ;/.??? No!!!'

>>> re.sub('\ |\?|\.|\!|\/|\;|\:', '', line)
'QDoIwriteNo'

Erläuterung

In regulären Ausdrücken (Regex) ist | ein logischer OR und \ Leerzeichen und Sonderzeichen, die tatsächliche Regex-Befehle sein könnten. sub steht für Substitution.

20

Für die umgekehrte Anforderung von only erlaubend bestimmten Zeichen in einer Zeichenfolge können Sie reguläre Ausdrücke mit einem Satzkomplementoperator [^ABCabc] verwenden. So entfernen Sie beispielsweise alles außer ASCII-Buchstaben, Ziffern und dem Bindestrich:

>>> import string
>>> import re
>>>
>>> phrase = '  There were "nine" (9) chick-peas in my pocket!!!      '
>>> allow = string.letters + string.digits + '-'
>>> re.sub('[^%s]' % allow, '', phrase)

'Therewerenine9chick-peasinmypocket'

Aus der Dokumentation zum regulären Ausdruck von Python :

Zeichen, die nicht innerhalb eines Bereichs liegen, können durch Ergänzung von .__ abgeglichen werden. der Satz. Wenn das erste Zeichen des Satzes '^' ist, werden alle Zeichen die nicht im Set sind, werden abgeglichen. Zum Beispiel stimmt [^5] mit .__ überein. Jedes Zeichen außer '5' und [^^] stimmt mit jedem Zeichen außer .__ überein. '^'. ^ hat keine besondere Bedeutung, wenn es nicht das erste Zeichen in der .__ ist. einstellen.

18
cod3monk3y

Der Fragesteller hätte es fast geschafft. Wie die meisten Dinge in Python ist die Antwort einfacher als Sie denken.

>>> line = "H E?.LL!/;O:: "  
>>> for char in ' ?.!/;:':  
...  line = line.replace(char,'')  
...
>>> print line
HELLO

Sie müssen nicht die verschachtelte if/for-Schleife ausführen, aber Sie müssen jeden Buchstaben einzeln prüfen.

18
mgold
line = line.translate(None, " ?.!/;:")
14
>>> s = 'a1b2c3'
>>> ''.join(c for c in s if c not in '123')
'abc'
10
eatkin

Zeichenfolgen sind in Python nicht veränderbar. Die replace-Methode gibt nach dem Ersetzen eine neue Zeichenfolge zurück. Versuchen:

for char in line:
    if char in " ?.!/;:":
        line = line.replace(char,'')
7
Greg Hewgill

Mit filter benötigen Sie nur eine Zeile

line = filter(lambda char: char not in " ?.!/;:", line)

Dies behandelt den String als iterierbar und prüft jedes Zeichen, wenn lambdaTrue zurückgibt:

>>> help(filter)
Help on built-in function filter in module __builtin__:

filter(...)
    filter(function or None, sequence) -> list, Tuple, or string

    Return those items of sequence for which function(item) is true.  If
    function is None, return the items that are true.  If sequence is a Tuple
    or string, return the same type, else return a list.
5
serv-inc

Ich war überrascht, dass noch niemand die Verwendung des eingebauten empfohlen hatte filter Funktion.

    import operator
    import string # only for the example you could use a custom string

    s = "1212edjaq"

Angenommen, wir möchten alles herausfiltern, das keine Zahl ist. Die Verwendung der Filter-eingebauten Methode "... entspricht dem Generatorausdruck (Element für Element in iterierbar, wenn Funktion (Element))" [ Python 3 Builtins: Filter ]

    sList = list(s)
    intsList = list(string.digits)
    obj = filter(lambda x: operator.contains(intsList, x), sList)))

In Python 3 wird dies zurückgegeben 

    >>  <filter object @ hex>

Um eine gedruckte Zeichenfolge zu erhalten,

    nums = "".join(list(obj))
    print(nums)
    >> "1212"

Ich weiß nicht wie filter Was Effizienz anbelangt, ist es eine gute Sache, zu wissen, wie man sie benutzt, wenn man Listenverständnisse und dergleichen verwendet.

AKTUALISIEREN

Da Filter funktioniert, können Sie logischerweise auch das Listenverständnis verwenden. Was ich gelesen habe, soll es effizienter sein, da Lambdas die Wall Street Hedgefonds-Manager der Programmierfunktionswelt sind. Ein weiterer Pluspunkt ist, dass es sich um einen Einzeiler handelt, der keine Importe erfordert. Wenn Sie zum Beispiel dieselbe Zeichenfolge wie oben definiert verwenden,

      num = "".join([i for i in s if i.isdigit()])

Das ist es. Die Rückgabe ist eine Zeichenfolge aller Zeichen, die Ziffern in der ursprünglichen Zeichenfolge sind.

Wenn Sie eine bestimmte Liste akzeptabler/inakzeptabler Zeichen haben, müssen Sie nur den 'if'-Teil des Listenverständnisses anpassen.

      target_chars = "".join([i for i in s if i in some_list]) 

oder alternativ,

      target_chars = "".join([i for i in s if i not in some_list])
5
Dan Temkin
>>> # Character stripping
>>> a = '?abcd1234!!'
>>> t.lstrip('?')
'abcd1234!!'
>>> t.strip('?!')
'abcd1234'
4
Arihant Bansal

Hier sind einige Möglichkeiten, um diese Aufgabe zu erreichen:

def attempt1(string):
    return "".join([v for v in string if v not in ("a", "e", "i", "o", "u")])


def attempt2(string):
    for v in ("a", "e", "i", "o", "u"):
        string = string.replace(v, "")
    return string


def attempt3(string):
    import re
    for v in ("a", "e", "i", "o", "u"):
        string = re.sub(v, "", string)
    return string


def attempt4(string):
    return string.replace("a", "").replace("e", "").replace("i", "").replace("o", "").replace("u", "")


for attempt in [attempt1, attempt2, attempt3, attempt4]:
    print(attempt("murcielago"))

PS: Anstelle von "?.!/;:" verwenden die Beispiele die Vokale ... und ja, "murcielago" ist das spanische Wort, um bat zu sagen ... komisches Wort, da es alle Vokale enthält :)

PS2: Wenn Sie sich für die Leistung interessieren, können Sie diese Versuche mit einem einfachen Code wie dem folgenden messen:

import timeit


K = 1000000
for i in range(1,5):
    t = timeit.Timer(
        f"attempt{i}('murcielago')",
        setup=f"from __main__ import attempt{i}"
    ).repeat(1, K)
    print(f"attempt{i}",min(t))

In meiner Box bekommst du:

attempt1 2.2334518376057244
attempt2 1.8806643818474513
attempt3 7.214925774955572
attempt4 1.7271184513757465

Es scheint also, dass try4 der schnellste für diese spezielle Eingabe ist.

3
BPL

Hier ist meine Python 2/3 kompatible Version. Seit dem Übersetzen hat sich die API verändert. 

def remove(str_, chars):
    """Removes each char in `chars` from `str_`.

    Args:
        str_: String to remove characters from
        chars: String of to-be removed characters

    Returns:
        A copy of str_ with `chars` removed

    Example:
            remove("What?!?: darn;", " ?.!:;") => 'Whatdarn'
    """
    try:
        # Python2.x
        return str_.translate(None, chars)
    except TypeError:
        # Python 3.x
        table = {ord(char): None for char in chars}
        return str_.translate(table)
3
Bryce Guinta

Sie können auch eine Funktion verwenden, um andere Arten von regulären Ausdrücken oder Mustern durch die Verwendung einer Liste zu ersetzen. Damit können Sie regulären Ausdruck, Zeichenklasse und wirklich einfaches Textmuster mischen. Dies ist sehr nützlich, wenn Sie viele Elemente wie HTML-Elemente ersetzen müssen.

* Hinweis: funktioniert mit Python 3.x

import re  # Regular expression library


def string_cleanup(x, notwanted):
    for item in notwanted:
        x = re.sub(item, '', x)
    return x

line = "<title>My example: <strong>A text %very% $clean!!</strong></title>"
print("Uncleaned: ", line)

# Get rid of html elements
html_elements = ["<title>", "</title>", "<strong>", "</strong>"]
line = string_cleanup(line, html_elements)
print("1st clean: ", line)

# Get rid of special characters
special_chars = ["[[email protected]#$]", "%"]
line = string_cleanup(line, special_chars)
print("2nd clean: ", line)

In der Funktion string_cleanup werden Ihre Zeichenfolge x und Ihre Liste nicht als Argumente benötigt. Für jedes Element in dieser Liste von Elementen oder Mustern wird ein Ersatz vorgenommen, wenn er benötigt wird.

Die Ausgabe:

Uncleaned:  <title>My example: <strong>A text %very% $clean!!</strong></title>
1st clean:  My example: A text %very% $clean!!
2nd clean:  My example: A text very clean
1
Djidiouf
#!/usr/bin/python
import re

strs = "how^ much for{} the maple syrup? $20.99? That's[] ricidulous!!!"
print strs
nstr = re.sub(r'[?|$|.|!|a|b]',r' ',strs)#i have taken special character to remove but any #character can be added here
print nstr
nestr = re.sub(r'[^a-zA-Z0-9 ]',r'',nstr)#for removing special character
print nestr
1
pkm

Wie wäre es damit:

def text_cleanup(text):
    new = ""
    for i in text:
        if i not in " ?.!/;:":
            new += i
    return new
1
Wariat

Sie müssen Ihre str-Variable neu zuweisen:

for char in line:
if char in " ?.!/;:":
    line = line.replace(char,'')
1

Meine Methode, die ich verwenden würde, würde wahrscheinlich nicht so effizient funktionieren, aber sie ist sehr einfach. Ich kann mehrere Zeichen an verschiedenen Positionen auf einmal entfernen, indem ich das Slicing und die Formatierung .. __ verwendet. Hier ein Beispiel:

words = "things"
removed = "%s%s" % (words[:3], words[-1:])

Dies führt dazu, dass "entfernt" das Wort "dies" gehalten wird.

Die Formatierung kann für das Drucken von Variablen in der Mitte einer Druckzeichenfolge sehr hilfreich sein. Es kann einen beliebigen Datentyp mit einem% gefolgt vom Datentyp der Variablen einfügen. Alle Datentypen können% s verwenden, Floats (auch Dezimalzahlen genannt) und Ganzzahlen% d

Slicing kann zur komplizierten Steuerung von Strings verwendet werden. Wenn ich words [: 3] setze, kann ich alle Zeichen in der Zeichenfolge vom Anfang (der Doppelpunkt steht vor der Zahl, dies bedeutet "vom Anfang bis") bis zum 4. Zeichen ( es enthält das 4. Zeichen). Der Grund 3 ist bis zur 4. Position gleich, weil Python bei 0 beginnt. Wenn ich dann Word [-1:] setze, bedeutet dies das zweitletzte Zeichen bis zum Ende (der Doppelpunkt steht hinter der Zahl). Wenn Sie -1 setzen, wird Python vom letzten Zeichen und nicht vom ersten Zeichen gezählt. Python wird wieder bei 0 beginnen. Also bedeutet Word [-1:] im Wesentlichen 'vom vorletzten Zeichen bis zum Ende des Strings.

Wenn Sie also die Zeichen vor dem Zeichen, das ich entfernen möchte, und die Zeichen danach abschneiden und sie zusammenfügen, kann ich das unerwünschte Zeichen entfernen. Stell dir das wie eine Wurst vor. In der Mitte ist es schmutzig, also will ich es loswerden. Ich schneide einfach die beiden Enden ab, die ich möchte, und füge sie dann zusammen, ohne dass das unerwünschte Teil in der Mitte liegt. 

Wenn ich mehrere aufeinanderfolgende Zeichen entfernen möchte, verschiebe ich die Zahlen einfach im [] (Slicing-Teil). Oder wenn ich mehrere Charaktere aus verschiedenen Positionen entfernen möchte, kann ich einfach mehrere Scheiben auf einmal schieben.

Beispiele:

 words = "control"
 removed = "%s%s" % (words[:2], words[-2:])

entfernt entspricht "cool".

words = "impacts"
removed = "%s%s%s" % (words[1], words[3:5], words[-1])

entfernt entspricht "Macs".

In diesem Fall bedeutet [3: 5] Zeichen an Position 3 durch Zeichen an Position 5 (ausschließlich das Zeichen an der Endposition). 

Denken Sie daran: Python beginnt bei 0, so dass Sie dies auch tun müssen.

1
oisinvg

Sie können den regulären Ausdruck des re-Moduls ersetzen. Mit dem Ausdruck ^ können Sie genau das auswählen, was Sie von Ihrer Zeichenfolge wollen.

    import re
    text = "This is absurd!"
    text = re.sub("[^a-zA-Z]","",text) # Keeps only Alphabets
    print(text)

Die Ausgabe dazu wäre "Thisisabsurd". Es werden nur die nach dem Symbol ^ angegebenen Elemente angezeigt.

0
Shreyas Rajesh

Unten ein .. ohne Verwendung eines regulären Ausdruckskonzeptes .. 

ipstring ="text with [email protected]#$^&*( ends here"
opstring=''
for i in ipstring:
    if i.isalnum()==1 or i==' ':
        opstring+=i
    pass
print opstring
0
Sadheesh

Auch der untenstehende Ansatz funktioniert

line = "a,b,c,d,e"
alpha = list(line)
        while ',' in alpha:
            alpha.remove(',')
finalString = ''.join(alpha)
print(finalString)

ausgabe >> abcde

0
M2skills

sie können Set verwenden

    charlist = list(set(string.digits+string.ascii_uppercase) - set('10IO'))
    return ''.join([random.SystemRandom().choice(charlist) for _ in range(passlen)])
0
Xu Zhenlei

In Python 3.5

z.B.,

os.rename(file_name, file_name.translate({ord(c): None for c in '0123456789'}))

Um alle Zahlen aus der Zeichenfolge zu entfernen 

0
BonieSV

Rekursiver Split: s = string; Zeichen = Zeichen zum Entfernen

def strip(s,chars):
if len(s)==1:
    return "" if s in chars else s
return strip(s[0:int(len(s)/2)],chars) +  strip(s[int(len(s)/2):len(s)],chars)

beispiel: 

print(strip("Hello!","lo"))    #He!
0
matt

# für jede Datei in einem Verzeichnis, Dateinamen umbenennen

   file_list = os.listdir (r"D:\Dev\Python")

   for file_name in file_list:

       os.rename(file_name, re.sub(r'\d+','',file_name))
0
Robert Silva

Probier diese:

def rm_char(original_str, need2rm):
    ''' Remove charecters in "need2rm" from "original_str" '''
    return original_str.translate(str.maketrans('','',need2rm))

Diese Methode funktioniert gut in Python 3.5.2

0
Joseph Lee