836 Stimmen

Beste Methode zum Entfernen von Interpunktionszeichen aus einer Zeichenkette

Es scheint einen einfacheren Weg zu geben als:

import string
s = "string. With. Punctuation?" # Sample string 
out = s.translate(string.maketrans("",""), string.punctuation)

Gibt es eine?

4 Stimmen

Das scheint mir ziemlich einfach zu sein. Warum wollen Sie es ändern? Wenn Sie es einfacher haben wollen, verpacken Sie einfach, was Sie gerade geschrieben haben, in eine Funktion.

3 Stimmen

Nun, es schien nur ein bisschen hackish zu sein, mit Art von einem Nebeneffekt von str.translate, um die Arbeit zu tun. Ich dachte, es könnte etwas mehr wie str.strip(chars), die auf die gesamte Zeichenfolge anstelle von nur die Grenzen, die ich verpasst hatte gearbeitet werden.

2 Stimmen

Das hängt auch von den Daten ab. Die Verwendung bei Daten, die Servernamen mit Unterstrichen als Teil des Namens enthalten (was an manchen Orten recht häufig vorkommt), könnte schlecht sein. Seien Sie sicher, dass Sie die Daten kennen und wissen, was sie enthalten, oder Sie könnten am Ende mit einer Teilmenge des Problems clbuttic.

6voto

>>> s = "string. With. Punctuation?"
>>> s = re.sub(r'[^\w\s]','',s)
>>> re.split(r'\s*', s)

['string', 'With', 'Punctuation']

2 Stimmen

Bitte geben Sie weitere Informationen an. Von reinen Code- und "Probier das mal"-Antworten wird abgeraten, da sie keinen durchsuchbaren Inhalt enthalten und nicht erklären, warum jemand "das mal probieren" sollte.

6voto

krinker Punkte 1064

Als Update habe ich das @Brian-Beispiel in Python 3 umgeschrieben und Änderungen vorgenommen, um den Regex-Kompilierschritt innerhalb der Funktion zu verschieben. Mein Gedanke dabei war, jeden einzelnen Schritt, der für das Funktionieren der Funktion erforderlich ist, zeitlich zu begrenzen. Vielleicht verwenden Sie verteiltes Computing und können das Regex-Objekt nicht zwischen Ihren Workern teilen und müssen re.compile Schritt bei jedem Arbeiter. Außerdem war ich neugierig, zwei verschiedene Implementierungen von maketrans für Python 3 zu testen

table = str.maketrans({key: None for key in string.punctuation})

gegen

table = str.maketrans('', '', string.punctuation)

Außerdem habe ich eine weitere Methode zur Verwendung von Mengen hinzugefügt, bei der ich die Schnittfunktion nutze, um die Anzahl der Iterationen zu verringern.

Dies ist der vollständige Code:

import re, string, timeit

s = "string. With. Punctuation"

def test_set(s):
    exclude = set(string.punctuation)
    return ''.join(ch for ch in s if ch not in exclude)

def test_set2(s):
    _punctuation = set(string.punctuation)
    for punct in set(s).intersection(_punctuation):
        s = s.replace(punct, ' ')
    return ' '.join(s.split())

def test_re(s):  # From Vinko's solution, with fix.
    regex = re.compile('[%s]' % re.escape(string.punctuation))
    return regex.sub('', s)

def test_trans(s):
    table = str.maketrans({key: None for key in string.punctuation})
    return s.translate(table)

def test_trans2(s):
    table = str.maketrans('', '', string.punctuation)
    return(s.translate(table))

def test_repl(s):  # From S.Lott's solution
    for c in string.punctuation:
        s=s.replace(c,"")
    return s

print("sets      :",timeit.Timer('f(s)', 'from __main__ import s,test_set as f').timeit(1000000))
print("sets2      :",timeit.Timer('f(s)', 'from __main__ import s,test_set2 as f').timeit(1000000))
print("regex     :",timeit.Timer('f(s)', 'from __main__ import s,test_re as f').timeit(1000000))
print("translate :",timeit.Timer('f(s)', 'from __main__ import s,test_trans as f').timeit(1000000))
print("translate2 :",timeit.Timer('f(s)', 'from __main__ import s,test_trans2 as f').timeit(1000000))
print("replace   :",timeit.Timer('f(s)', 'from __main__ import s,test_repl as f').timeit(1000000))

Dies sind meine Ergebnisse:

sets      : 3.1830138750374317
sets2      : 2.189873124472797
regex     : 7.142953420989215
translate : 4.243278483860195
translate2 : 2.427158243022859
replace   : 4.579746678471565

6voto

aloha Punkte 4044

Ich war auf der Suche nach einer wirklich einfachen Lösung, und die habe ich bekommen:

import re 

s = "string. With. Punctuation?" 
s = re.sub(r'[\W\s]', ' ', s)

print(s)
'string  With  Punctuation '

5voto

ngub05 Punkte 506

Hier ist eine Lösung ohne Regex.

import string

input_text = "!where??and!!or$$then:)"
punctuation_replacer = string.maketrans(string.punctuation, ' '*len(string.punctuation))    
print ' '.join(input_text.translate(punctuation_replacer).split()).strip()

Output>> where and or then
  • Ersetzt die Interpunktionen durch Leerzeichen
  • Ersetzen Sie mehrere Leerzeichen zwischen Wörtern durch ein einzelnes Leerzeichen
  • Entfernen Sie die Leerzeichen am Ende, falls vorhanden, mit strip()

5voto

Dehua Li Punkte 373

Warum benutzt das keiner von Ihnen?

 ''.join(filter(str.isalnum, s)) 

Zu langsam?

4 Stimmen

Beachten Sie, dass dabei auch Leerzeichen entfernt werden.

0 Stimmen

Trotzdem nützlich, wenn Sie zuerst str.split() ausführen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X