Remover pontuações em JavaScript até que é uma tarefa fácil, mas remover acentos, deixando apenas as letras já é um pouco mais complicado. Independente da situação, disponibilizo abaixo algumas funções minimalistas que servem para ambos os casos.
Como remover acentos em JavaScript
Para simplesmente remover acentos e cedilha de uma string e retornar a mesma string sem os acentos, podemos usar o método String.prototype.normalize do ES6, seguido de um String.prototype.replace:
const str = 'ÁÉÍÓÚáéíóúâêîôûàèìòùÇç';
const parsed = str.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
console.log(parsed);
Explicação
O método normalize foi introduzido na versão ES6 do JavaScript, em 2015. E serve para converter uma string em seu formato Unicode normalizado. Neste caso utilizamos o parâmetro NFD que é capaz de separar os acentos das letras e retornar seus códigos Unicode.
Para ter uma noção melhor de como funciona essa conversão para Unicode, acompanhe abaixo:
// String Á em UTF-18 tem 1 dígito
'Á'.length; // 1
// String Á em Unicode tem 2 dígitos: \u0041\u0301
'Á'.normalize('NFD').length; // 2
// Se tentarmos representar Unicode, vamos obter o seguinte resultado
console.log('\u0041\u0301'); // Á
Em seguida o método replace substitui todas as ocorrências de caracteres diacríticos, combinando-os na sequencia Unicode \u0300 - \u036F, outra vantagem do ES6 que foi adicionada para permitir ranges Unicode em RegEx.
Removendo todos os caracteres especiais em JavaScript
Para remover os acentos e outros caracteres especiais como /.?!(), basta usar a mesma fórmula acima, só que substituir tudo menos letras e números.
const str = 'ÁÉÍÓÚáéíóúâêîôûàèìòùÇç/.,~!@#$%&_-12345';
const parsed = str.normalize('NFD').replace(/([\u0300-\u036f]|[^0-9a-zA-Z])/g, '');
console.log(parsed);
Explicação
Para entender o que acontece no código acima, sugiro ler o parágrafo anterior onde falei sobre o método normalize e Unicode.
A única adição neste caso foi criar 2 grupos no regex através de ([ grupo 1 ]|[ grupo 2 ])
e adicionar ao grupo 2 a expressão regular [^0-9a-zA-Z]
, que significa: tudo o que não (^) for de 0-9, de a-z ou de A-Z, seja também substituído.
Se você não quiser remover espaços, basta adicionar \s
:
str.normalize('NFD').replace(/([\u0300-\u036f]|[^0-9a-zA-Z\s])/g, '')
Substituindo caracteres especiais
Outro caso de uso bastante recorrente é a necessidade de limpar os acentos e em seguida substituir caracteres especiais por algum outro, exemplo: "Uma frase qualquer" -> "Uma-frase-qualquer".
Existe uma expressão regular muito boa para substituir caracteres que não sejam letras ou números comuns, porém esta expressão também acaba com acentos.
'Esta é uma frase'.replace(/[^\w\-]+/g, '-'); // Esta-uma-frase
Se quisermos remover somente os acentos e depois substituirmos outros caracteres especiais, precisamos seguir mais ou menos o que foi proposto no primeiro exemplo:
'Esta é uma frase'.normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/[^\w\-]+/g, '-');
Mas de repente você também precisa substituir hífens desnecessários, como no caso de "Esta é uma frase!!!" virar "Esta-e-uma-frase---".
Uma função completa que remove acentos, substitui caracteres especiais por hífen, também removendo hífens adicionais:
const replaceSpecialChars = (str) => {
return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '') // Remove acentos
.replace(/([^\w]+|\s+)/g, '-') // Substitui espaço e outros caracteres por hífen
.replace(/\-\-+/g, '-') // Substitui multiplos hífens por um único hífen
.replace(/(^-+|-+$)/, ''); // Remove hífens extras do final ou do inicio da string
}
console.log(replaceSpecialChars('Esta é uma frase!!!'));
Se quiser ainda usar essa mesma função para limpar uma URL, basta adicionar um toLowerCase()
ao final e está resolvido!
Acho que cobri todos os casos mais recorrentes ao trabalhar com acentos e caracteres especiais em JavaScript. Infelizmente essa é uma dificuldade adicional de qualquer input latino que geralmente não é embutida nas linguagens de programação.