2012-05-14 17 views
15

Czy istnieje pythonic sposób zrobić to, co robi metoda str.strip(), z wyjątkiem wszystkich wystąpień, a nie tylko tych na początku i końcu ciągu?Usunięcie wszystkich wystąpień kilku znaków z ciągu znaków

Przykład:

>> '::2012-05-14 18:10:20.856000::'.strip(' -.:') 
>> '2012-05-14 18:10:20.856000' 

Chcę

>> '::2012-05-14 18:10:20.856000::'.crazy_function(' -.:') 
>> '20120514181020856000' 

Czy Python dostarcza mi wbudowany crazy_function ???

Mogę łatwo zrobić to programowo, ale chcę wiedzieć, czy jest na to wbudowany. Nie można znaleźć. Dziękuję za pomoc.

Odpowiedz

21

Użyj funkcji translate usunąć niechciane znaki:

>>> '::2012-05-14 18:10:20.856000::'.translate(None, ' -.:') 
'20120514181020856000' 

Upewnij się, że łańcuch jest str typu i nie unicode, jako parametry funkcji nie będzie takie samo. Dla Unicode, użyj następującej składni; polega ona na budowaniu dict z porządkowych unicode od znaków do usunięcia i mapować je do None:

>>> u'::2012-05-14 18:10:20.856000::'.translate({ord(k):None for k in u' -.:'}) 
u'20120514181020856000' 

Niektóre czasy dla porównania wyników z re:

>>> timeit.timeit("""re.sub(r"[ -.:]", r"", "'::2012-05-14 18:10:20.856000::'")""","import re") 
7.352270301875713 
>>> timeit.timeit("""'::2012-05-14 18:10:20.856000::'.translate(None, ' -.:')""") 
0.5894893344550951 
+0

Wolę wbudowane rozwiązanie takiego rozwiązania nad napisanym przez Nick Craig-Wood. Ale zastanawiam się: pod względem wydajności, co jest lepsze? Mogę się mylić, ale ta funkcja "tłumacz" prawdopodobnie korzysta z funkcji regexp. – Francisco

+0

@Francisco: Sądzę, że istnieją dwie różne funkcje tłumaczenia. Wersja 3-arugmentowa działa z _ sekwencji bajtów_, używa tablicy translacji, która szybko się świeci. Wersja unicode działa na _strings_, zastępuje znaki jeden po drugim i jest tak samo powolna jak regexp, jeśli nie wolniejsza. Nadal używam wyrażeń regularnych dla twojego problemu, ponieważ mieszanie _strings_ i _byte sequence_ nigdy nie jest dobrym pomysłem, nawet w python2. – georg

+0

@ thg435: W moim problemie konkretnie wersja bajtowa jest w porządku. Tworzę kody identyfikacyjne oparte na str (datetime.datetime.now()) i dodaje do niego dodatkowy kawałek łańcucha. Tak więc, unicode nie stanowi dla mnie problemu. – Francisco

4

Można to zrobić dość łatwo z re.sub

>>> import re 
>>> re.sub(r"[ -.:]", r"", "'::2012-05-14 18:10:20.856000::'") 
'20120514181020856000' 
>>> 
1

nie, nie myślę, że jest wbudowany.

chciałbym zrobić to w ten sposób:

>>> s = '::2012-05-14 18:10:20.856000::' 
>>> 
>>> ''.join(x for x in s if x not in ' -.:') 
'20120514181020856000' 
>>> 
+1

Doh. Tłumaczyć. Oczywiście. – cdjc

+0

Dzięki, ale to "programowo". – Francisco

+0

Zobacz drugą odpowiedź, która używa translate –

Powiązane problemy