Fjern specifikke tegn fra en streng i Python

Jeg forsøger at fjerne bestemte tegn fra en streng ved hjælp af Python. Dette er den kode, jeg bruger lige nu. Desværre ser det ud til at gøre noget ved strengen.

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

Hvordan gør jeg dette korrekt?

Løsning

Strings i Python er immutable (kan ikke ændres). På grund af dette er effekten af line.replace(...) blot at skabe en ny streng, i stedet for at ændre den gamle. Du skal rebind (tildele) den til line for at få denne variabel til at tage den nye værdi, med disse tegn fjernet.

Desuden vil den måde du gør det på være ret langsom, relativt set. Det vil sandsynligvis også være lidt forvirrende for erfarne pythonatorer, som vil se en dobbelt-nested struktur og et øjeblik tro, at der foregår noget mere kompliceret.

Fra Python 2.6 og nyere Python 2.x-versioner * kan du i stedet bruge str.translate, (men læs videre om forskelle i Python 3):

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

eller erstatning af regulære udtryk med [re.sub]](https://docs.python.org/2/library/re.html#re.sub)

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

De tegn, der er omgivet af parenteser, udgør en tegnklasse. Alle tegn i line, som er i denne klasse, erstattes med den anden parameter til sub: en tom streng.

I Python 3 er strenge Unicode. Du bliver nødt til at oversætte lidt anderledes. kevpie nævner dette i en kommentar til et af svarene, og det er noteret i dokumentationen for str.translate.

Når du kalder translate-metoden for en Unicode-streng, kan du ikke overdrage den anden parameter, som vi brugte ovenfor. Du kan heller ikke overgive None som første parameter eller endda en oversættelsestabel fra string.maketrans. I stedet skal du overdrage en ordbog som den eneste parameter. Denne ordbog kortlægger ordinalværdierne af tegn (dvs. resultatet af at kalde ord på dem) til ordinalværdierne af de tegn, der skal erstatte dem, eller - hvilket er nyttigt for os - None for at angive, at de skal slettes.

Så for at udføre ovenstående dans med en Unicode-streng skal du kalde noget som

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

Her bruges dict.fromkeys og map til kortfattet at generere en ordbog, der indeholder

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

Endnu enklere er det, som et andet svar udtrykker det, at oprette ordbogen på stedet:

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

* Af hensyn til kompatibilitet med tidligere Pythons kan du oprette en "null" oversættelsestabel til at overdrage i stedet for None:

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

Her bruges string.maketrans til at oprette en oversættelsestabel, som blot er en streng, der indeholder tegn med ordinalværdierne 0 til 255.

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

Strings er uforanderlige i Python. Metoden replace returnerer en ny streng efter udskiftningen. Prøv:

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