Preciso remover todos os caracteres especiais, pontuação e espaços de uma string, para ter apenas letras e números.
Preciso remover todos os caracteres especiais, pontuação e espaços de uma string, para ter apenas letras e números.
Respostas:
Isso pode ser feito sem regex:
>>> string = "Special $#! characters spaces 888323"
>>> ''.join(e for e in string if e.isalnum())
'Specialcharactersspaces888323'
Você pode usar str.isalnum
:
S.isalnum() -> bool Return True if all characters in S are alphanumeric and there is at least one character in S, False otherwise.
Se você insistir em usar o regex, outras soluções funcionarão bem. No entanto, observe que, se isso puder ser feito sem o uso de uma expressão regular, essa é a melhor maneira de fazer isso.
isalnum()
e regex versões, eo regex é 50-75% mais rápido
Aqui está uma regex para corresponder a uma sequência de caracteres que não são letras ou números:
[^A-Za-z0-9]+
Aqui está o comando Python para fazer uma substituição de regex:
re.sub('[^A-Za-z0-9]+', '', mystring)
+
quantificador para melhorar a sua eficiência um pouco.)
[^A-Za-z0-9 ]+
Maneira mais curta:
import re
cleanString = re.sub('\W+','', string )
Se você quiser espaços entre palavras e números, substitua '' por ''
r'\W+'
- ligeiramente fora de tópico (e muito pedante), mas eu sugiro um hábito que todos os padrões de regex ser cordas matérias
Depois de ver isso, eu estava interessado em expandir as respostas fornecidas, descobrindo quais são executadas no menor período de tempo. Por isso, analisei algumas das respostas propostas com timeit
duas das seqüências de exemplo:
string1 = 'Special $#! characters spaces 888323'
string2 = 'how much for the maple syrup? $20.99? That s ricidulous!!!'
'.join(e for e in string if e.isalnum())
string1
- Resultado: 10.7061979771string2
- Resultado: 7.78372597694import re
re.sub('[^A-Za-z0-9]+', '', string)
string1
- Resultado: 7.10785102844string2
- Resultado: 4.12814903259import re
re.sub('\W+','', string)
string1
- Resultado: 3.11899876595string2
- Resultado: 2.78014397621Os resultados acima são um produto do menor resultado retornado de uma média de: repeat(3, 2000000)
O exemplo 3 pode ser 3x mais rápido que o exemplo 1 .
''.join([*filter(str.isalnum, string)])
Eu acho que filter(str.isalnum, string)
funciona
In [20]: filter(str.isalnum, 'string with special chars like !,#$% etcs.')
Out[20]: 'stringwithspecialcharslikeetcs'
No Python3, a filter( )
função retornaria um objeto iterável (em vez de uma string diferente da acima). É preciso se juntar novamente para obter uma string do itertable:
''.join(filter(str.isalnum, string))
ou para passar list
no uso da junção ( não tenho certeza, mas pode ser um pouco rápido )
''.join([*filter(str.isalnum, string)])
note: descompactar em [*args]
válido a partir do Python> = 3.5
map
, filter
e reduce
retorna objeto itertable vez. Ainda em Python3 +, preferirei ''.join(filter(str.isalnum, string))
(ou passar a lista no uso de junção ''.join([*filter(str.isalnum, string)])
) à resposta aceita.
''.join(filter(str.isalnum, string))
é uma melhoria filter(str.isalnum, string)
, pelo menos para ler. Essa é realmente a maneira Pythreenic (sim, você pode usar isso) para fazer isso?
filter(str.isalnum, string)
não retornam string no Python3 como filter( )
em Python3 retorna iterador ao invés de tipo de argumento ao contrário de Python-2 +.
#!/usr/bin/python
import re
strs = "how much for the maple syrup? $20.99? That's ricidulous!!!"
print strs
nstr = re.sub(r'[?|$|.|!]',r'',strs)
print nstr
nestr = re.sub(r'[^a-zA-Z0-9 ]',r'',nstr)
print nestr
você pode adicionar mais caracteres especiais e que serão substituídos por "" não significa nada, ou seja, eles serão removidos.
Diferentemente do que todo mundo usava regex, eu tentava excluir todos os caracteres que não são o que eu quero, em vez de enumerar explicitamente o que não quero.
Por exemplo, se eu quiser apenas caracteres de 'a a z' (maiúsculas e minúsculas) e números, excluiria todo o resto:
import re
s = re.sub(r"[^a-zA-Z0-9]","",s)
Isso significa "substituir todo caractere que não seja um número ou um caractere no intervalo 'a a z' ou 'A a Z' por uma string vazia".
De fato, se você inserir o caractere especial ^
no primeiro lugar do seu regex, receberá a negação.
Dica adicional: se você também precisar diminuir o resultado em minúsculas , poderá tornar o regex ainda mais rápido e fácil, desde que não encontre maiúsculas agora.
import re
s = re.sub(r"[^a-z0-9]","",s.lower())
Supondo que você queira usar uma regex e que deseje / precise do código 2.x com reconhecimento de Unicode que esteja pronto para 2to3:
>>> import re
>>> rx = re.compile(u'[\W_]+', re.UNICODE)
>>> data = u''.join(unichr(i) for i in range(256))
>>> rx.sub(u'', data)
u'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\xaa\xb2 [snip] \xfe\xff'
>>>
A abordagem mais genérica é usar as 'categorias' da tabela unicodedata que classifica cada caractere único. Por exemplo, o código a seguir filtra apenas caracteres imprimíveis com base em sua categoria:
import unicodedata
# strip of crap characters (based on the Unicode database
# categorization:
# http://www.sql-und-xml.de/unicode-database/#kategorien
PRINTABLE = set(('Lu', 'Ll', 'Nd', 'Zs'))
def filter_non_printable(s):
result = []
ws_last = False
for c in s:
c = unicodedata.category(c) in PRINTABLE and c or u'#'
result.append(c)
return u''.join(result).replace(u'#', u' ')
Veja o URL fornecido acima para todas as categorias relacionadas. Naturalmente, você também pode filtrar pelas categorias de pontuação.
$
o final de cada linha?
string.punctuation contém os seguintes caracteres:
'! "# $% & \' () * +, -. / :; <=>? @ [\] ^ _` {|} ~ '
Você pode usar as funções de conversão e maketrans para mapear pontuações para valores vazios (substituir)
import string
'This, is. A test!'.translate(str.maketrans('', '', string.punctuation))
Resultado:
'This is A test'
Use traduzir:
import string
def clean(instr):
return instr.translate(None, string.punctuation + ' ')
Advertência: Funciona apenas em seqüências ascii.
TypeError: translate() takes exactly one argument (2 given)
com py3.4
import re
my_string = """Strings are amongst the most popular data types in Python. We can create the strings by enclosing characters in quotes. Python treats single quotes the
o mesmo que aspas duplas. "" "
# if we need to count the word python that ends with or without ',' or '.' at end
count = 0
for i in text:
if i.endswith("."):
text[count] = re.sub("^([a-z]+)(.)?$", r"\1", i)
count += 1
print("The count of Python : ", text.count("python"))
import re
abc = "askhnl#$%askdjalsdk"
ddd = abc.replace("#$%","")
print (ddd)
e você verá seu resultado como
'askhnlaskdjalsdk
re
mas nunca o usou. Seus replace
critérios funcionam apenas para essa sequência específica. E se a sua string for abc = "askhnl#$%!askdjalsdk"
? Acho que não funcionará em nada além do #$%
padrão. Pode querer ajustá-lo
Remoção de pontuações, números e caracteres especiais
Exemplo: -
Código
combi['tidy_tweet'] = combi['tidy_tweet'].str.replace("[^a-zA-Z#]", " ")
Obrigado :)
Para outros idiomas, como alemão, espanhol, dinamarquês, francês etc que contêm caracteres especiais (como o alemão "trema", como ü
, ä
, ö
) simplesmente adicioná-los para a cadeia de pesquisa regex:
Exemplo para alemão:
re.sub('[^A-ZÜÖÄa-z0-9]+', '', mystring)