associação pythonbrasil[11] django zope/plone planet Início Logado como (Entrar)

Revisão 9e 2006-01-17 23:55:05

Excluir mensagem

TiradorDeAcentos

Tirador de Acentos

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".

# -*- coding: UTF-8 -*-

#Arrancador de acentos
#Copyright  (2004) João S. O. Bueno 
#Permissao para uso e modificacao conforme a LGPL.


#uso: check_alphanum (string) retorna verdadeiro se a string é imprimivivel
#strip_diacriticals : troca todos os acentos pelos equivalentes nao acentuados.
# e retorna a string alterada

import copy

conversion= { "á": "a", "é": "e", "í": "i", "ó": "o", "ú": "u",
     "à": "a", "è": "e", "ì": "i", "ò": "o", "ù": "u",
     "â": "a", "ê": "e", "î": "i", "ô": "o", "û": "u",
     "ã": "a", "õ": "o", "ñ": "n", "ç":"c",
     "Á": "A", "É": "E", "Í": "I", "Ó": "O", "Ú": "U",
     "À": "A", "È": "E", "Ì": "I", "Ò": "O", "Ù": "U",
     "Â": "A", "Ê": "E", "Î": "I", "Ô": "O", "Û": "U",
     "Ã": "A", "Õ": "O", "Ñ": "N", "Ç": "C",
     "Ü": "U", "û":"u", "Ä":"A", "ä":"a", "Ë":"E", "ë":"e",
     "Ï":"I", "ï":"i", "Ö":"O", "ö":"o", "ð":"?", "ß":"ss",
      "Å":"A","å":"a", "ø":"o", "Ø":"O", "Þ":"?" , "æ":"ae"
     }

alphanum_ops_CHECK=0
alphanum_ops_FIX=1

def _alphanum_util (string, operation):
    """check if all characters are in printable range
    and valid in roman alphabet languages"""
    global alphanum_ops_CHECK, alphanum_ops_FIX
    global conversion
    ok=1
    out_string=""
    skip=0
    aux=len(string)
    for i in xrange(aux):
        if skip:
            skip-=1
            continue
        char=string[i]
        num=ord(char)
        if num>=32 and num<=127:
            out_string+=char
        else:
            if num> 127 and i<aux-1 and conversion.has_key (string[i]+string[i+1]):
                out_string+=conversion[string[i]+string[i+1]]
                skip=1
            else:
                out_string+="?"
                ok=0
                if operation==alphanum_ops_CHECK:
                    return ok
                #the following values are picked from utf-8 specification
                #and mean the number of bytes following the first byte > 0xc0
                #that are part of the same utf-8 character
                if num >= 0xf0:
                    skip=3
                elif num >= 0xe0:
                    skip-2
                elif num>= 0xc0:
                    skip=1
                else:
                    skip=0
    if operation==alphanum_ops_CHECK:
        return ok
    else:
        return out_string

def check_alphanum (string):
    """check if all characters are in printable range and
    valid in romam alphabet languages"""
    global alphanum_ops_CHECK, alphanum_ops_FIX
    return _alphanum_util (string, alphanum_ops_CHECK)

def strip_diacriticals (string):
    """replace non ASCII characters  for '?' ' or equiv.
    letter if it is an western european accented letter."""
    global alphanum_ops_CHECK, alphanum_ops_FIX
    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


João S. O. Bueno