Zastąp wszystkie niealfanumeryczne znaki w ciągu

100

Mam ciąg, którym chcę zastąpić dowolny znak, który nie jest standardowym znakiem lub liczbą, na przykład (az lub 0-9), gwiazdką. Na przykład „h ^ & ell”., | Ow] {+ orld ”jest zastępowane przez„ h * ell * o * w * orld ”. Zwróć uwagę, że wiele znaków, takich jak „^ &”, zostanie zastąpionych jedną gwiazdką. Jak bym to zrobił?

tchadwik
źródło

Odpowiedzi:

184

Regex na ratunek!

import re

s = re.sub('[^0-9a-zA-Z]+', '*', s)

Przykład:

>>> re.sub('[^0-9a-zA-Z]+', '*', 'h^&ell`.,|o w]{+orld')
'h*ell*o*w*orld'
nneonneo
źródło
7
Jeśli często zajmujesz się Unicode, być może będziesz musiał zachować wszystkie symbole Unicode inne niż ASCII:re.sub("[\x00-\x2F\x3A-\x40\x5B-\x60\x7B-\x7F]+", " ", ":%# unicode ΣΘΙП@./\n")
zhazha
Jeśli chcesz zachować spacje w łańcuchu, po prostu dodaj spację w nawiasach: s = re.sub ('[^ 0-9a-zA-Z] +', '*', s)
stackPusher
2
Jeśli wykonujesz więcej niż jedno zastąpienie, będzie to działać nieco szybciej, jeśli wstępnie skompilujesz wyrażenie regularne, np.import re; regex = re.compile('[^0-9a-zA-Z]+'); regex.sub('*', 'h^&ell.,|o w]{+orld')
Chris
Zwróć też uwagę, że \Wdotyczy znaków niebędących słowami, jest prawie taki sam, ale dopuszcza podkreślenie jako znak słowa (nie wiem dlaczego): docs.python.org/3.6/library/re.html#index-32
JHS
37

Sposób pytoniczny.

print "".join([ c if c.isalnum() else "*" for c in s ])

Nie dotyczy to jednak grupowania wielu kolejnych niepasujących znaków, np

"h^&i => "h**inie "h*i"tak jak w rozwiązaniach regex.

baloan
źródło
11

Próbować:

s = filter(str.isalnum, s)

w Pythonie3:

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

Edycja: zdał sobie sprawę, że OP chce zamienić znaki nieznakowe na „*”. Moja odpowiedź nie pasuje

Don
źródło
11

Użyj, \Wktóre jest równoważne z [^a-zA-Z0-9_]. Sprawdź dokumentację, https://docs.python.org/2/library/re.html

Import re
s =  'h^&ell`.,|o w]{+orld'
replaced_string = re.sub(r'\W+', '*', s)
output: 'h*ell*o*w*orld'

aktualizacja: to rozwiązanie wyklucza również podkreślenie. Jeśli chcesz, aby wykluczyć tylko alfabety i liczby, bardziej odpowiednie jest rozwiązanie nneonneo.

psun
źródło
1
Zauważ, że \Wjest to równoważne[^a-zA-Z0-9_] tylko w Pythonie 2.x. W Pythonie 3.x \W+jest równoważne [^a-zA-Z0-9_]tylko wtedy, gdy użyto re.ASCII/ re.Aflag.
Wiktor Stribiżew