Jag försöker ta bort specifika tecken från en sträng med hjälp av Python. Detta är den kod jag använder just nu. Tyvärr verkar den inte göra något med strängen.
for char in line:
if char in " ?.!/;:":
line.replace(char,'')
Hur gör jag detta på rätt sätt?
Strängar i Python är immutabla (kan inte ändras). På grund av detta är effekten av line.replace(...)
bara att skapa en ny sträng, snarare än att ändra den gamla. Du måste återbinda (tilldela) den till line
för att få den variabeln att ta emot det nya värdet, med dessa tecken borttagna.
Dessutom kommer det sätt du gör det på att vara ganska långsamt, relativt sett. Det är också troligt att det blir lite förvirrande för erfarna pythonatorer, som kommer att se en struktur med dubbla höljen och för ett ögonblick tro att det är något mer komplicerat som pågår.
Från och med Python 2.6 och nyare Python 2.x-versioner * kan du istället använda str.translate
, (men läs vidare om skillnaderna i Python 3):
line = line.translate(None, '!@#$')
eller ersättning av reguljära uttryck med re.sub
import re
line = re.sub('[!@#$]', '', line)
Tecknen inom parentes utgör en teckenklass. Alla tecken i line
som ingår i den klassen ersätts med den andra parametern till sub
: en tom sträng.
I Python 3 är strängar Unicode. Du måste översätta lite annorlunda. kevpie nämner detta i en kommentar till ett av svaren, och det noteras i dokumentationen för str.translate
.
När du anropar translate
-metoden för en Unicode-sträng kan du inte lämna över den andra parametern som vi använde ovan. Du kan inte heller lämna över None
som första parameter, eller ens en översättningstabell från string.maketrans
. Istället lämnar du över en ordbok som enda parameter. Denna ordbok mappar ordinalvärdena av tecken (dvs. resultatet av att kalla ord
på dem) till ordinalvärdena av de tecken som ska ersätta dem, eller - vilket är användbart för oss - None
för att indikera att de ska raderas.
Så för att göra ovanstående dans med en Unicode-sträng skulle du kalla något i stil med
translation_table = dict.fromkeys(map(ord, '!@#$'), None)
unicode_line = unicode_line.translate(translation_table)
Här används dict.fromkeys
och map
för att kortfattat generera en ordbok som innehåller
{ord('!'): None, ord('@'): None, ...}
Ännu enklare, som ett annat svar uttrycker det, är att skapa ordboken på plats:
unicode_line = unicode_line.translate({ord(c): None for c in '!@#$'})
* För att vara kompatibel med tidigare Pythons kan du skapa en "null" översättningstabell som du kan skicka i stället för None
:
import string
line = line.translate(string.maketrans('', ''), '!@#$')
Här används string.maketrans
för att skapa en översättningstabell, som bara är en sträng som innehåller tecken med ordningsvärdena 0 till 255.