Estou tendo problemas para remover caracteres não utf8 da string, que não estão sendo exibidos corretamente. Os caracteres são assim 0x97 0x61 0x6C 0x6F (representação hexadecimal)
Qual é a melhor maneira de removê-los? Expressão regular ou outra coisa?
Respostas:
Usando uma abordagem regex:
Ele procura sequências UTF-8 e as captura no grupo 1. Também corresponde a bytes únicos que não puderam ser identificados como parte de uma sequência UTF-8, mas não os captura. Substituição é tudo o que foi capturado no grupo 1. Isso remove efetivamente todos os bytes inválidos.
É possível reparar a string, codificando os bytes inválidos como caracteres UTF-8. Mas se os erros forem aleatórios, isso pode deixar alguns símbolos estranhos.
EDITAR:
!empty(x)
corresponderá a valores não vazios ("0"
é considerado vazio).x != ""
corresponderá a valores não vazios, incluindo"0"
.x !== ""
corresponderá a qualquer coisa, exceto""
.x != ""
parece o melhor para usar neste caso.Também acelerei um pouco a partida. Em vez de combinar cada caractere separadamente, ele combina sequências de caracteres UTF-8 válidos.
fonte
$regex = <<<'END'
do PHP <5.3.x?elseif (!empty($captures([2])) {
e você deve usar em!== ""
vez de vazio, pois"0"
é considerado vazio. Além disso, essa função é muito lenta, isso poderia ser feito mais rápido?Se você aplicar
utf8_encode()
a uma string UTF8, ela retornará uma saída UTF8 truncada.Fiz uma função que aborda todas essas questões. É chamado
Encoding::toUTF8()
.Você não precisa saber qual é a codificação de suas strings. Pode ser Latin1 (ISO8859-1), Windows-1252 ou UTF8, ou a string pode ter uma combinação deles.
Encoding::toUTF8()
irá converter tudo para UTF8.Fiz isso porque um serviço estava me dando um feed de dados todos bagunçados, misturando essas codificações na mesma string.
Uso:
Incluí outra função, Encoding :: fixUTF8 (), que corrigirá cada string UTF8 que pareça um produto ilegível por ter sido codificado em UTF8 várias vezes.
Uso:
Exemplos:
irá produzir:
Baixar:
https://github.com/neitanod/forceutf8
fonte
Você pode usar mbstring:
... irá remover caracteres inválidos.
Consulte: Substituindo caracteres UTF-8 inválidos por pontos de interrogação, mbstring.substitute_character parece ignorado
fonte
<0x1a>
<0x1a>
, embora não seja um caractere imprimível, é uma sequência UTF-8 perfeitamente válida. Você pode ter problemas com caracteres não imprimíveis? Verifique isto: stackoverflow.com/questions/1176904/…ini_set('mbstring.substitute_character', 'none');
caso contrário, recebia pontos de interrogação no resultado.Esta função remove todos os caracteres NÃO ASCII, é útil, mas não resolve a questão:
Esta é minha função que sempre funciona, independentemente da codificação:
Como funciona:
fonte
í
caractere no campo de endereço, que É um caractere UTF-8 válido, consulte a tabela . Moral: não confie nas mensagens de erro de API :)É isso que estou usando. Parece funcionar muito bem. Retirado de http://planetozh.com/blog/2005/01/remove-invalid-characters-in-utf-8/
fonte
tente isto:
De acordo com o manual do iconv , a função terá o primeiro parâmetro como o conjunto de caracteres de entrada, o segundo parâmetro como o conjunto de caracteres de saída e o terceiro como a string de entrada real.
Se você definir o conjunto de caracteres de entrada e saída como UTF-8 e anexar o
//IGNORE
sinalizador ao conjunto de caracteres de saída, a função descartará (removerá) todos os caracteres na string de entrada que não podem ser representados pelo conjunto de caracteres de saída. Assim, filtrando a string de entrada em vigor.fonte
//IGNORE
não parece suprimir o aviso de que UTF-8 inválido está presente (o que, é claro, eu conheço e desejo corrigir). Um comentário bem avaliado no manual parece pensar que é um bug há alguns anos.iconv
. @halfer Talvez seus dados de entrada não sejam do utf-8. Outra opção é fazer uma reconversão para ascii e, em seguida, voltar para utf-8 novamente. No meu caso, useiiconv
como$output = iconv("UTF-8//", "ISO-8859-1//IGNORE", $input );
O texto pode conter caracteres não utf8 . Tente fazer primeiro:
Você pode ler mais sobre isso aqui: http://php.net/manual/en/function.mb-convert-encoding.php news
fonte
UConverter pode ser usado desde o PHP 5.5. UConverter é a melhor escolha se você usar extensão intl e não usar mbstring.
htmlspecialchars podem ser usados para remover sequências de bytes inválidas desde o PHP 5.4. Htmlspecialchars é melhor do que preg_match para lidar com grandes tamanhos de bytes e precisão. Muitas das implementações erradas usando expressões regulares podem ser vistas.
fonte
Criei uma função que exclui caracteres UTF-8 inválidos de uma string. Estou usando para limpar a descrição de 27.000 produtos antes de gerar o arquivo de exportação XML.
fonte
ord()
retorna resultados no intervalo 0-255. O giganteif
nesta função testa os intervalos de Unicode queord()
nunca retornarão. Se alguém quiser esclarecer por que essa função funciona dessa maneira, gostaria de receber o insight.Bem-vindo a 2019 e ao
/u
modificador em regex que tratará de caracteres multibyte UTF-8 para vocêSe você usar apenas
mb_convert_encoding($value, 'UTF-8', 'UTF-8')
, ainda assim ficará com caracteres não imprimíveis em sua stringEste método irá:
mb_convert_encoding
\r
,\x00
(NULL-byte) e outros caracteres de controle compreg_replace
método:
[:print:]
corresponder a todos os caracteres e\n
novas linhas imprimíveis e remover todo o restoVocê pode ver a tabela ASCII abaixo. Os caracteres imprimíveis variam de 32 a 127, mas a nova linha
\n
é uma parte dos caracteres de controle que variam de 0 a 31, então temos que adicionar nova linha ao regex/[^[:print:]\n]/u
Você pode tentar enviar strings através do regex com caracteres fora do intervalo de impressão, como
\x7F
(DEL),\x1B
(Esc) etc. e ver como eles são removidoshttps://www.tehplayground.com/q5sJ3FOddhv1atpR
fonte
php-mbstring
não é empacotado em php por padrão.fonte
Do patch recente para o módulo analisador JSON de feeds do Drupal:
Se você está preocupado, sim, ele retém espaços como caracteres válidos.
Fiz o que eu precisava. Ele remove os caracteres emoji comuns hoje em dia que não cabem no conjunto de caracteres 'utf8' do MySQL e que me deram erros como "SQLSTATE [HY000]: Erro geral: 1366 Valor de string incorreto".
Para obter detalhes, consulte https://www.drupal.org/node/1824506#comment-6881382
fonte
iconv
é muito melhor do que o antigo regexp moda baseadapreg_replace
, wich é obsoleto hoje em dia.ereg_replace()
, desculpe.Talvez não seja a solução mais precisa, mas realiza o trabalho com uma única linha de código:
utf8_decode
irá converter os caracteres em um ponto de interrogação;str_replace
irá remover os pontos de interrogação.fonte
Portanto, as regras são que o primeiro octlet UTF-8 tem o bit alto definido como marcador e, em seguida, 1 a 4 bits para indicar quantos octetos adicionais; então, cada um dos octlets adicionais deve ter os dois bits altos definidos como 10.
O pseudo-python seria:
Esta mesma lógica deve ser traduzida para php. No entanto, não está claro que tipo de remoção deve ser feito quando você obtém um caractere malformado.
fonte
c = (ch << 1)
fará(c & 1)
zero na primeira vez, pulando o loop. O teste provavelmente deveria ser(c & 128)
Para remover todos os caracteres Unicode fora do plano de linguagem básico Unicode:
fonte
Um pouco diferente da pergunta, mas o que estou fazendo é usar HtmlEncode (string),
pseudo código aqui
entrada e saída
Eu sei que não é perfeito, mas faz o trabalho para mim.
fonte
funciona em nosso serviço
fonte
Que tal o iconv:
http://php.net/manual/en/function.iconv.php
Não usei dentro do PHP, mas sempre funcionou bem para mim na linha de comando. Você pode obtê-lo para substituir caracteres inválidos.
fonte