Specifieke tekens uit een string verwijderen in Python

Ik'm probeer specifieke karakters uit een string te verwijderen met Python. Dit is de code die ik nu gebruik. Helaas lijkt het niets te doen met de string.

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

Hoe doe ik dit op de juiste manier?

Oplossing

Strings in Python zijn immutable (kunnen niet veranderd worden). Daarom is het effect van line.replace(...) alleen maar om een nieuwe string te maken, in plaats van de oude te veranderen. Je moet het rebinden (toewijzen) aan line om die variabele de nieuwe waarde te laten aannemen, met die tekens verwijderd.

Ook zal de manier waarop je het doet nogal traag zijn, relatief gezien. Het zal waarschijnlijk ook een beetje verwarrend zijn voor ervaren python gebruikers, die een dubbel-nest structuur zullen zien en even denken dat er iets ingewikkelder aan de hand is.

Vanaf Python 2.6 en nieuwere Python 2.x versies *, kun je in plaats daarvan str.translate gebruiken, (maar lees verder voor Python 3 verschillen):

line = line.translate(None, '!@#$')

of reguliere expressie vervanging met re.sub

import re
line = re.sub('[!@#$]', '', line)

De tekens tussen haakjes vormen een karakterklasse. Alle tekens in line die tot die klasse behoren, worden vervangen door de tweede parameter van sub: een lege tekenreeks.

In Python 3 zijn strings Unicode. Je'zult een beetje anders moeten vertalen. kevpie vermeldt dit in een commentaar op een van de antwoorden, en het'wordt opgemerkt in de documentatie voor str.translate.

Bij het aanroepen van de translate methode van een Unicode string, kun je niet de tweede parameter doorgeven die we hierboven gebruikten. Je kunt ook niet None doorgeven als eerste parameter, of zelfs een vertaaltabel van string.maketrans. In plaats daarvan geef je een woordenboek door als enige parameter. Dit woordenboek brengt de ordinale waarden van tekens (d.w.z. het resultaat van het aanroepen van ord op hen) over op de ordinale waarden van de tekens die hen moeten vervangen, of - voor ons nuttig - None om aan te geven dat ze moeten worden verwijderd.

Dus om de bovenstaande dans te doen met een Unicode string zou je iets aanroepen als

translation_table = dict.fromkeys(map(ord, '!@#$'), None)
unicode_line = unicode_line.translate(translation_table)

Hier worden dict.fromkeys en map gebruikt om beknopt een woordenboek te genereren met

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

Nog eenvoudiger, zoals een ander antwoord het stelt, maak het woordenboek ter plaatse:

unicode_line = unicode_line.translate({ord(c): None for c in '!@#$'})

* Voor compatibiliteit met vroegere Pythons, kunt u een "null" vertaaltabel maken om door te geven in plaats van None:

import string
line = line.translate(string.maketrans('', ''), '!@#$')

Hier wordt string.maketrans gebruikt om een vertaaltabel te maken, wat gewoon een tekenreeks is die de tekens bevat met de ordinale waarden 0 tot 255.

Commentaren (7)
line = line.translate(None, " ?.!/;:")
Commentaren (2)

Teksten zijn onveranderlijk in Python. De replace methode geeft een nieuwe string terug na de vervanging. Probeer maar eens:

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