Preciso substituir todos os caracteres não ASCII (\ x00- \ x7F) por um espaço. Estou surpreso que isso não seja fácil no Python, a menos que esteja faltando alguma coisa. A função a seguir simplesmente remove todos os caracteres não ASCII:
def remove_non_ascii_1(text):
return ''.join(i for i in text if ord(i)<128)
E este substitui caracteres não ASCII pela quantidade de espaços conforme a quantidade de bytes no ponto de código do caractere (ou seja, o –
caractere é substituído por 3 espaços):
def remove_non_ascii_2(text):
return re.sub(r'[^\x00-\x7F]',' ', text)
Como posso substituir todos os caracteres não ASCII por um único espaço?
Da miríade de semelhantes SO perguntas , nenhum endereço de caráter de substituição como oposição a descascar , e , adicionalmente, tratar todos os caracteres não-ascii não um personagem específico.
–
. É esse cara .Respostas:
Sua
''.join()
expressão é filtrada , removendo qualquer coisa que não seja ASCII; você poderia usar uma expressão condicional:Isso lida com os caracteres um por um e ainda usaria um espaço por caractere substituído.
Sua expressão regular deve substituir apenas caracteres não ASCII consecutivos por um espaço:
Observe o
+
lá.fonte
str.join()
precisa de uma lista (ela passará os valores duas vezes) e uma expressão de gerador será primeiro convertida em uma. Fornecer uma lista de compreensão é simplesmente mais rápido. Veja este post .–
caractere é substituído por 3 espaços" na pergunta implica que a entrada é uma bytestring (não Unicode) e, portanto, o Python 2 é usado (caso contrário''.join
, falharia). Se o OP desejar um espaço único por ponto de código Unicode, a entrada deverá ser decodificada primeiro no Unicode.Para você obter a representação mais semelhante da sua string original, recomendo o módulo unidecode :
Então você pode usá-lo em uma string:
fonte
דותן
. No entanto, no sentido geral, isso é ótimo, obrigado!Para processamento de caracteres , use cadeias Unicode:
Mas observe que você ainda terá um problema se sua string contiver caracteres Unicode decompostos (caracteres separados e sinais de destaque combinados, por exemplo):
fonte
ud.normalize('NFC',s)
para combinar marcas, mas nem todas as combinações são representadas por pontos de código únicos. Você precisaria de uma solução mais inteligente olhando paraud.category()
o personagem.\X
(cluster de grafemas expandidos) O regex (suportado peloregex
módulo) permite iterar sobre esses caracteres (nota: "grafemas não necessariamente combinam seqüências de caracteres e combinações de caracteres não são necessariamente grafemas" ).Se o caractere de substituição puder ser '?' em vez de um espaço, sugiro
result = text.encode('ascii', 'replace').decode()
:Resultados:
fonte
Que tal este?
fonte
Como uma abordagem nativa e eficiente, você não precisa usar
ord
nenhum loop sobre os caracteres. Apenas codifiqueascii
e ignore os erros.A seguir, apenas os caracteres não-ascii serão removidos:
Agora, se você deseja substituir os caracteres excluídos, faça o seguinte:
fonte
encode
retornará uma bytestring, portanto, lembre-se disso. Além disso, esse método não remove caracteres como nova linha.Possivelmente para uma pergunta diferente, mas estou fornecendo minha versão da resposta do @ Alvero (usando o unidecode). Eu quero fazer uma faixa "regular" nas minhas strings, ou seja, o começo e o fim da minha string para caracteres de espaço em branco e, em seguida, substituir apenas outros caracteres de espaço em branco por um espaço "regular", ou seja,
para
,
Primeiro, substituímos todos os espaços não unicode por um espaço regular (e os juntamos novamente),
E então dividimos isso novamente, com a divisão normal do python, e removemos cada "bit",
E, por fim, junte-os novamente, mas somente se a sequência for aprovada em um
if
teste,E com isso,
safely_stripped('ㅤㅤㅤㅤCeñíaㅤmañanaㅤㅤㅤㅤ')
retorna corretamente'Ceñía mañana'
.fonte