it-swarm.com.de

In Python werden alle Zeichen außer alphanumerischen Zeichen aus einer Zeichenfolge entfernt

Was ist der beste Weg, um alle nicht alphanumerischen Zeichen mit Python aus einer Zeichenfolge zu entfernen?

Die in der PHP - Variante dieser Frage vorgestellten Lösungen werden wahrscheinlich mit einigen geringfügigen Anpassungen funktionieren, erscheinen mir aber nicht sehr 'Pythonic'.

Für das Protokoll möchte ich nicht nur Punkte und Kommas (und andere Satzzeichen) entfernen, sondern auch Anführungszeichen, Klammern usw.

259
Mark van Lent

Ich habe gerade einige Funktionen aus Neugier eingestellt. Bei diesen Tests entferne ich nicht alphanumerische Zeichen aus der Zeichenfolge string.printable (Teil des integrierten string-Moduls).

$ python -m timeit -s \
     "import string" \
     "''.join(ch for ch in string.printable if ch.isalnum())" 
10000 loops, best of 3: 57.6 usec per loop

$ python -m timeit -s \
    "import string" \
    "filter(str.isalnum, string.printable)"                 
10000 loops, best of 3: 37.9 usec per loop

$ python -m timeit -s \
    "import re, string" \
    "re.sub('[\W_]', '', string.printable)"
10000 loops, best of 3: 27.5 usec per loop

$ python -m timeit -s \
    "import re, string" \
    "re.sub('[\W_]+', '', string.printable)"                
100000 loops, best of 3: 15 usec per loop

$ python -m timeit -s \
    "import re, string; pattern = re.compile('[\W_]+')" \
    "pattern.sub('', string.printable)" 
100000 loops, best of 3: 11.2 usec per loop
271

Reguläre Ausdrücke zur Rettung:

import re
re.sub(r'\W+', '', your_string)

Durch die Python-Definition '\W == [^a-zA-Z0-9_], die alle numbers, letters und _ ausschließt

203
Ants Aasma

Verwenden Sie die Methode str.translate () .

Vorausgesetzt, Sie werden dies häufig tun:

(1) Erstellen Sie anschließend eine Zeichenfolge mit allen Zeichen, die Sie löschen möchten:

delchars = ''.join(c for c in map(chr, range(256)) if not c.isalnum())

(2) Wann immer Sie eine Saite bearbeiten möchten:

scrunched = s.translate(None, delchars)

Die Einrichtungskosten sind wahrscheinlich mit re.compile vergleichbar; Die Grenzkosten sind viel niedriger:

C:\junk>\python26\python -mtimeit -s"import string;d=''.join(c for c in map(chr,range(256)) if not c.isalnum());s=string.printable" "s.translate(None,d)"
100000 loops, best of 3: 2.04 usec per loop

C:\junk>\python26\python -mtimeit -s"import re,string;s=string.printable;r=re.compile(r'[\W_]+')" "r.sub('',s)"
100000 loops, best of 3: 7.34 usec per loop

Hinweis: Die Verwendung von string.printable als Benchmark-Daten gibt dem Muster '[\ W _] +' einen unfairen Vorteil. ; Alle nicht-alphanumerischen Zeichen befinden sich in einer Reihe ... Bei typischen Daten müssten mehrere Ersetzungen vorgenommen werden:

C:\junk>\python26\python -c "import string; s = string.printable; print len(s),repr(s)"
100 '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;=>[email protected][\\]^_`{|}~ \t\n\r\x0b\x0c'

Folgendes passiert, wenn Sie re.sub etwas mehr Arbeit geben:

C:\junk>\python26\python -mtimeit -s"d=''.join(c for c in map(chr,range(256)) if not c.isalnum());s='foo-'*25" "s.translate(None,d)"
1000000 loops, best of 3: 1.97 usec per loop

C:\junk>\python26\python -mtimeit -s"import re;s='foo-'*25;r=re.compile(r'[\W_]+')" "r.sub('',s)"
10000 loops, best of 3: 26.4 usec per loop
66
John Machin

Du könntest es versuchen:

print ''.join(ch for ch in some_string if ch.isalnum())
36
ars
>>> import re
>>> string = "[email protected]£$%[};'\""
>>> pattern = re.compile('\W')
>>> string = re.sub(pattern, '', string)
>>> print string
Kl13
13
DisplacedAussie

Wie wäre es mit:

def ExtractAlphanumeric(InputString):
    from string import ascii_letters, digits
    return "".join([ch for ch in InputString if ch in (ascii_letters + digits)])

Dies geschieht durch Verwendung des Listenverständnisses, um eine Liste der Zeichen in InputString zu erstellen, wenn sie in den kombinierten ascii_letters- und digits-Zeichenfolgen vorhanden sind. Es fügt die Liste dann zu einem String zusammen.

11
DrAl

Im Anschluss an einige andere Antworten biete ich eine wirklich einfache und flexible Möglichkeit, eine Menge von Zeichen zu definieren, auf die Sie den Inhalt eines Strings beschränken möchten. In diesem Fall erlaube ich alphanumerische PLUS-Striche und Unterstriche. Fügen Sie einfach Zeichen aus meinem PERMITTED_CHARS hinzu oder entfernen Sie sie entsprechend Ihrem Anwendungsfall. 

PERMITTED_CHARS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-" 
someString = "".join(c for c in someString if c in PERMITTED_CHARS)
3
BuvinJ
for char in my_string:
    if not char.isalnum():
        my_string = my_string.replace(char,"")
3
Junior Ogun

Timing mit zufälligen Strings von ASCII Ausdrucken:

from inspect import getsource
from random import sample
import re
from string import printable
from timeit import timeit

pattern_single = re.compile(r'[\W]')
pattern_repeat = re.compile(r'[\W]+')
translation_tb = str.maketrans('', '', ''.join(c for c in map(chr, range(256)) if not c.isalnum()))


def generate_test_string(length):
    return ''.join(sample(printable, length))


def main():
    for i in range(0, 60, 10):
        for test in [
            lambda: ''.join(c for c in generate_test_string(i) if c.isalnum()),
            lambda: ''.join(filter(str.isalnum, generate_test_string(i))),
            lambda: re.sub(r'[\W]', '', generate_test_string(i)),
            lambda: re.sub(r'[\W]+', '', generate_test_string(i)),
            lambda: pattern_single.sub('', generate_test_string(i)),
            lambda: pattern_repeat.sub('', generate_test_string(i)),
            lambda: generate_test_string(i).translate(translation_tb),

        ]:
            print(timeit(test), i, getsource(test).lstrip('            lambda: ').rstrip(',\n'), sep='\t')


if __== '__main__':
    main()

Ergebnis (Python 3.7):

       Time       Length                           Code                           
6.3716264850008880  00  ''.join(c for c in generate_test_string(i) if c.isalnum())
5.7285426190064750  00  ''.join(filter(str.isalnum, generate_test_string(i)))
8.1875841680011940  00  re.sub(r'[\W]', '', generate_test_string(i))
8.0002205439959650  00  re.sub(r'[\W]+', '', generate_test_string(i))
5.5290945199958510  00  pattern_single.sub('', generate_test_string(i))
5.4417179649972240  00  pattern_repeat.sub('', generate_test_string(i))
4.6772285089973590  00  generate_test_string(i).translate(translation_tb)
23.574712151996210  10  ''.join(c for c in generate_test_string(i) if c.isalnum())
22.829975890002970  10  ''.join(filter(str.isalnum, generate_test_string(i)))
27.210196289997840  10  re.sub(r'[\W]', '', generate_test_string(i))
27.203713296003116  10  re.sub(r'[\W]+', '', generate_test_string(i))
24.008979928999906  10  pattern_single.sub('', generate_test_string(i))
23.945240008994006  10  pattern_repeat.sub('', generate_test_string(i))
21.830899796994345  10  generate_test_string(i).translate(translation_tb)
38.731336012999236  20  ''.join(c for c in generate_test_string(i) if c.isalnum())
37.942474347000825  20  ''.join(filter(str.isalnum, generate_test_string(i)))
42.169366310001350  20  re.sub(r'[\W]', '', generate_test_string(i))
41.933375883003464  20  re.sub(r'[\W]+', '', generate_test_string(i))
38.899814646996674  20  pattern_single.sub('', generate_test_string(i))
38.636144253003295  20  pattern_repeat.sub('', generate_test_string(i))
36.201238164998360  20  generate_test_string(i).translate(translation_tb)
49.377356811004574  30  ''.join(c for c in generate_test_string(i) if c.isalnum())
48.408927293996385  30  ''.join(filter(str.isalnum, generate_test_string(i)))
53.901889764994850  30  re.sub(r'[\W]', '', generate_test_string(i))
52.130339455994545  30  re.sub(r'[\W]+', '', generate_test_string(i))
50.061149017004940  30  pattern_single.sub('', generate_test_string(i))
49.366573111998150  30  pattern_repeat.sub('', generate_test_string(i))
46.649754120997386  30  generate_test_string(i).translate(translation_tb)
63.107938601999194  40  ''.join(c for c in generate_test_string(i) if c.isalnum())
65.116287978999030  40  ''.join(filter(str.isalnum, generate_test_string(i)))
71.477421126997800  40  re.sub(r'[\W]', '', generate_test_string(i))
66.027950693998720  40  re.sub(r'[\W]+', '', generate_test_string(i))
63.315361931003280  40  pattern_single.sub('', generate_test_string(i))
62.342320287003530  40  pattern_repeat.sub('', generate_test_string(i))
58.249303059004890  40  generate_test_string(i).translate(translation_tb)
73.810345625002810  50  ''.join(c for c in generate_test_string(i) if c.isalnum())
72.593953348005020  50  ''.join(filter(str.isalnum, generate_test_string(i)))
76.048324580995540  50  re.sub(r'[\W]', '', generate_test_string(i))
75.106637657001560  50  re.sub(r'[\W]+', '', generate_test_string(i))
74.681338128997600  50  pattern_single.sub('', generate_test_string(i))
72.430461594005460  50  pattern_repeat.sub('', generate_test_string(i))
69.394243567003290  50  generate_test_string(i).translate(translation_tb)

str.maketrans & str.translate ist am schnellsten, enthält jedoch alle Nicht-ASCII-Zeichen .re.compile & pattern.sub ist langsamer, aber irgendwie schneller als ''.join & filter.

0
Solomon Ucko
sent = "".join(e for e in sent if e.isalpha())
0
Tom Kalvijn