var str="INFO] :谷���新道, ひば���ヶ丘2丁���, ひばりヶ���, 東久留米市 (Higashikurume)";
e eu preciso remover todos os caracteres não ascii da string,
significa str contém apenas "INFO] (Higashikurume)";
Respostas:
ASCII está no intervalo de 0 a 127, então:
str.replace(/[^\x00-\x7F]/g, "");
Também pode ser feito com uma afirmação positiva de remoção, como esta:
textContent = textContent.replace(/[\u{0080}-\u{FFFF}]/gu,"");
Isso usa Unicode. Em Javascript, ao expressar unicode para uma expressão regular, os caracteres são especificados com a sequência de escape, \u{xxxx}
mas também o sinalizador 'u'
deve apresentar; observe que a regex tem sinalizadores 'gu'
.
Chamei isso de "afirmação positiva de remoção" no sentido de que uma afirmação "positiva" expressa quais caracteres remover, enquanto uma afirmação "negativa" expressa quais letras não remover. Em muitos contextos, a afirmação negativa, conforme declarada nas respostas anteriores, pode ser mais sugestiva para o leitor. O circunflexo " ^
" diz "não" e o intervalo \x00-\x7F
diz "ascii", então os dois juntos dizem "não ascii".
textContent = textContent.replace(/[^\x00-\x7F]/g,"");
Essa é uma ótima solução para falantes de inglês que se preocupam apenas com o idioma inglês, e também é uma boa resposta para a pergunta original. Mas, em um contexto mais geral, nem sempre se pode aceitar o viés cultural de supor que "todos os não-ascii são ruins". Para contextos onde não ASCII é usado, mas ocasionalmente precisa ser removido, a afirmação positiva do Unicode é um ajuste melhor.
Uma boa indicação de que caracteres de largura zero e não imprimíveis estão embutidos em uma string é quando a propriedade "length" da string é positiva (diferente de zero), mas parece (isto é, imprime como) uma string vazia. Por exemplo, isso apareceu no depurador do Chrome, para uma variável chamada "textContent":
> textContent
""
> textContent.length
7
Isso me levou a querer ver o que havia naquela string.
> encodeURI(textContent)
"%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B"
Essa sequência de bytes parece estar na família de alguns caracteres Unicode que são inseridos por processadores de texto em documentos e, em seguida, encontram seu caminho em campos de dados. Mais comumente, esses símbolos ocorrem no final de um documento. O espaço de largura zero "%E2%80%8B"
pode ser inserido pelo CK-Editor (CKEditor).
encodeURI() UTF-8 Unicode html Meaning
----------- -------- ------- ------- -------------------
"%E2%80%8B" EC 80 8B U 200B ​ zero-width-space
"%E2%80%8E" EC 80 8E U 200E ‎ left-to-right-mark
"%E2%80%8F" EC 80 8F U 200F ‏ right-to-left-mark
Algumas referências sobre:
http://www.fileformat.info/info/unicode/char/200B/index.htm
https://en.wikipedia.org/wiki/Left-to-right_mark
Observe que, embora a codificação do caractere incorporado seja UTF-8, a codificação na expressão regular não é. Embora o caractere seja incorporado na string como três bytes (no meu caso) de UTF-8, as instruções na expressão regular devem usar o Unicode de dois bytes. Na verdade, o UTF-8 pode ter até quatro bytes de comprimento; é menos compacto do que Unicode porque usa o bit (ou bits) alto para escapar da codificação ascii padrão. Isso é explicado aqui:
textContent = textContent.replace(/[\u{0080}-\u{FFFF}]/gu,"");
não funciona no IE (pelo menos no IE 11). Ele falha com o erro: SCRIPT5021 : intervalo inválido no conjunto de caracteres
Você pode usar o seguinte regex para substituir caracteres não ASCII
str = str.replace(/[^A-Za-z 0-9 \.,\?""!@#\$%\^&\*\(\)-_=\+;:<>\/\\\|\}\{\[\]`~]*/g, '')
No entanto, observe que espaços, dois-pontos e vírgulas são todos ASCII válidos, então o resultado será
> str
"INFO] :, , , (Higashikurume)"
[]
significam qualquer caractere, mas [^]
significam o oposto - correspondem a qualquer caractere que não esteja entre colchetes.
Nenhuma dessas respostas lida corretamente com tabulações, novas linhas, retornos de carro e algumas não lidam com ASCII estendido e Unicode. Isso irá MANTER tabulações e novas linhas, mas removerá caracteres de controle e qualquer coisa fora do conjunto ASCII. Clique no botão "Executar este snippet de código" para testar. Há algum javascript novo chegando, então no futuro (2020+?) Você pode ter que fazer, \u{FFFFF}
mas ainda não
console.log("line 1\nline2 \n\ttabbed\nF̸̡̢͓̳̜̪̟̳̠̻̖͐̂̍̅̔̂͋͂͐l̸̢̹̣̤̙͚̱͓̖̹̻̣͇͗͂̃̈͝a̸̢̡̬͕͕̰̖͍̮̪̬̍̏̎̕͘ͅv̸̢̛̠̟̄̿i̵̮͌̑ǫ̶̖͓͎̝͈̰̹̫͚͓̠̜̓̈́̇̆̑͜ͅ".replace(/[\x00-\x08\x0E-\x1F\x7F-\uFFFF]/g, ''))
Para usar ASCII com acentos:
var str = str.replace(/[^\x00-\xFF]/g, "");