TiradorDeAcentos

Tirador de Acentos

Atenção: a receita RemovedorDeAcentos possui uma solução bem mais simples. (e feita "do jeito certo" - esta aqui eu fiz quando estava aprendendo python e nem conhecia os objetos unicode (js))

Um pequeno fragmento de código que pode ser usado para remover acentos de strings. Exemplo: "Facção" vira "Faccao"

O Código foi escrito para fazer isso em strings UTF-8, consideravelmente mais complexas do que as strings ISO-8859-1.

Uma pequena alteração (para mais simples) se faz necessária para funcionar com strings ISO-8859-1.

Uma vez que eu precisava também da funcionalidade de "verificação de imprimibilidade" de uma string, e o código seria muito parecido, abaixo as duas estão implementadas, com um "layer" de interface para cada funcionalidade.

Disponibilizo o código aqui sob a LGPL. Não estou distribuindo junto o texto full da LGPL, mas o público alvo saberá acha-lo. Então, os que forem usar o código, o façam sabendo que "mesmo não tendo assinado nada, os termos declarados na LGPL são a única licença para uso deste código a que têm acesso, e sua violação implica em perda dos direitos de uso deste código".

   1 #!/usr/local/bin/python
   2 # -*- coding: UTF-8 -*-
   3 
   4 #Arrancador de acentos
   5 #Copyright  (2004) João S. O. Bueno 
   6 #Permissao para uso e modificacao conforme a LGPL.
   7 
   8 
   9 #uso: check_alphanum (string) retorna verdadeiro se a string é imprimivivel
  10 #strip_diacriticals : troca todos os acentos pelos equivalentes nao acentuados.
  11 # e retorna a string alterada
  12 
  13 import copy
  14 
  15 conversion= { "á": "a", "é": "e", "í": "i", "ó": "o", "ú": "u",
  16      "à": "a", "è": "e", "ì": "i", "ò": "o", "ù": "u",
  17      "â": "a", "ê": "e", "î": "i", "ô": "o", "û": "u",
  18      "ã": "a", "õ": "o", "ñ": "n", "ç":"c",
  19      "Á": "A", "É": "E", "Í": "I", "Ó": "O", "Ú": "U",
  20      "À": "A", "È": "E", "Ì": "I", "Ò": "O", "Ù": "U",
  21      "Â": "A", "Ê": "E", "Î": "I", "Ô": "O", "Û": "U",
  22      "Ã": "A", "Õ": "O", "Ñ": "N", "Ç": "C",
  23      "Ü": "U", "û":"u", "Ä":"A", "ä":"a", "Ë":"E", "ë":"e",
  24      "Ï":"I", "ï":"i", "Ö":"O", "ö":"o", "ð":"?", "ß":"ss",
  25       "Å":"A","å":"a", "ø":"o", "Ø":"O", "Þ":"?" , "æ":"ae"
  26      }
  27 
  28 alphanum_ops_CHECK=0
  29 alphanum_ops_FIX=1
  30 
  31 def _alphanum_util (string, operation):
  32     """check if all characters are in printable range
  33     and valid in roman alphabet languages"""
  34     global alphanum_ops_CHECK, alphanum_ops_FIX
  35     global conversion
  36     ok=1
  37     out_string=""
  38     skip=0
  39     aux=len(string)
  40     for i in xrange(aux):
  41         if skip:
  42             skip-=1
  43             continue
  44         char=string[i]
  45         num=ord(char)
  46         if num>=32 and num<=127:
  47             out_string+=char
  48         else:
  49             if num> 127 and i<aux-1 and conversion.has_key (string[i]+string[i+1]):
  50                 out_string+=conversion[string[i]+string[i+1]]
  51                 skip=1
  52             else:
  53                 out_string+="?"
  54                 ok=0
  55                 if operation==alphanum_ops_CHECK:
  56                     return ok
  57                 #the following values are picked from utf-8 specification
  58                 #and mean the number of bytes following the first byte > 0xc0
  59                 #that are part of the same utf-8 character
  60                 if num >= 0xf0:
  61                     skip=3
  62                 elif num >= 0xe0:
  63                     skip-2
  64                 elif num>= 0xc0:
  65                     skip=1
  66                 else:
  67                     skip=0
  68     if operation==alphanum_ops_CHECK:
  69         return ok
  70     else:
  71         return out_string
  72 
  73 def check_alphanum (string):
  74     """check if all characters are in printable range and
  75     valid in romam alphabet languages"""
  76     global alphanum_ops_CHECK, alphanum_ops_FIX
  77     return _alphanum_util (string, alphanum_ops_CHECK)
  78 
  79 def strip_diacriticals (string):
  80     """replace non ASCII characters  for '?' ' or equiv.
  81     letter if it is an western european accented letter."""
  82     global alphanum_ops_CHECK, alphanum_ops_FIX
  83     return _alphanum_util (string, alphanum_ops_FIX)

PS. Obviamente o código acima tem que ser gravado em UTF-8.

Interessante, mas acho que existe um jeito mais prático usando o metodo translate do unicode. Funciona assim:

   1 d = {192: u'A', 193: u'A', 194: u'A', 195: u'A', 196: u'A', 197: u'A', 
   2      199: u'C', 200: u'E', 201: u'E', 202: u'E', 203: u'E', 204: u'I', 
   3      205: u'I', 206: u'I', 207: u'I', 209: u'N', 210: u'O', 211: u'O', 
   4      212: u'O', 213: u'O', 214: u'O', 216: u'O', 217: u'U', 218: u'U', 
   5      219: u'U', 220: u'U', 221: u'Y', 224: u'a', 225: u'a', 226: u'a', 
   6      227: u'a', 228: u'a', 229: u'a', 231: u'c', 232: u'e', 233: u'e', 
   7      234: u'e', 235: u'e', 236: u'i', 237: u'i', 238: u'i', 239: u'i', 
   8      241: u'n', 242: u'o', 243: u'o', 244: u'o', 245: u'o', 246: u'o', 
   9      248: u'o', 249: u'u', 250: u'u', 251: u'u', 252: u'u', 253: u'y', 
  10      255: u'y'}
  11 s = unicode(string_com_acentos, 'iso-8859-1').translate(d)

Note que isso funciona para o charset iso-8859-1, mas deve funcionar para qualquer outro charset, na pior das hipoteses basta trocar os números por u´Á', u'À', e assim por diante, só usei números porque foi como consegui essa tabela e não estava com paciência de fazer do outro jeito. -- RafaelAlmeida


Usei um terceiro método para obter a "desacentuação" tanto a partir de UTF 8 quanto a partir de ISO 8859-1:

   1 #!/usr/bin/env python
   2 # -*- coding: utf-8 -*-
   3 # Se você quiser "desacentuar" strings em ISO 8859-1, basta trocar a
   4 # linha acima por "coding: iso-8859-1" e salvar o código-fonte com o
   5 # encoding citado.
   6 
   7 _table = { 
   8     "á" : "a", "à" : "a", "â" : "a", "ä" : "a", "ã" : "a", "å" : "a",
   9     "é" : "e", "è" : "e", "ê" : "e", "ë" : "e",
  10     "í" : "i", "ì" : "i", "î" : "i", "ï" : "i",
  11     "ó" : "o", "ò" : "o", "ô" : "o", "ö" : "o", "õ" : "o", "ø" : "o", 
  12     "ú" : "u", "ù" : "u", "û" : "u", "ü" : "u",
  13     "ñ" : "n", "ç" : "c",
  14     "Á" : "A", "À" : "A", "Â" : "A", "Ä" : "A", "Ã" : "A", "Å" : "A",
  15     "É" : "E", "È" : "E", "Ê" : "E", "Ë" : "E", 
  16     "Í" : "I", "Ì" : "I", "Î" : "I", "Ï" : "I", 
  17     "Ó" : "O", "Ò" : "O", "Ô" : "O", "Ö" : "O", "Õ" : "O", "Ø" : "O",
  18     "Ú" : "U", "Ù" : "U", "Û" : "U", "Ü" : "U", 
  19     "Ñ" : "N", "Ç" : "C",
  20     "ß" : "ss", "Þ" : "d" , "æ" : "ae"
  21 }
  22 
  23 
  24 def asciize(s):
  25     """ 
  26     Converts a entire string to a ASCII only string.
  27    
  28     string
  29         The string to be converted.
  30     """
  31     for original, plain in _table.items():
  32         s = s.replace(original, plain)
  33     return s

Note que ele não faz a conversão em ambos os encodings a partir do mesmo código-fonte, mas exige algumas alterações. Entretatno, acho que são alterações mais localizadas que nos códigos anteriores, de modo que são mais fáceis de executar. -- AdamVictorNazarethBrandizzi


João S. O. Bueno

TiradorDeAcentos (editada pela última vez em 2009-08-06 17:52:37 por JoaoSOBueno)