Удалите non-utf8 символы из строки

, Если url не начинается '/'

, Берут URL текущей страницы, обрубают все мимо последнего '/'; тогда добавьте относительный URL.

Еще, если url начинается '/'

, Берут URL текущей страницы и обрубают все направо от сингла '/'; тогда добавьте URL.

Еще, если url запускается с # или?

Берут URL текущей страницы и просто добавляют url

<час>

Hope, это работает на Вас

101
задан Ned Batchelder 14 July 2010 в 13:11
поделиться

5 ответов

Использование подхода с использованием регулярных выражений:

$regex = <<<'END'
/
  (
    (?: [\x00-\x7F]                 # single-byte sequences   0xxxxxxx
    |   [\xC0-\xDF][\x80-\xBF]      # double-byte sequences   110xxxxx 10xxxxxx
    |   [\xE0-\xEF][\x80-\xBF]{2}   # triple-byte sequences   1110xxxx 10xxxxxx * 2
    |   [\xF0-\xF7][\x80-\xBF]{3}   # quadruple-byte sequence 11110xxx 10xxxxxx * 3 
    ){1,100}                        # ...one or more times
  )
| .                                 # anything else
/x
END;
preg_replace($regex, '$1', $text);

Он ищет последовательности UTF-8 и захватывает их в группу 1. Он также сопоставляет отдельные байты, которые не могут быть идентифицированы как часть UTF -8, но не захватывает их. Замена - это то, что было записано в группу 1. Это эффективно удаляет все недопустимые байты.

Можно исправить строку, закодировав недопустимые байты как символы UTF-8. Но если ошибки случайные, это может привести к появлению некоторых странных символов.

$regex = <<<'END'
/
  (
    (?: [\x00-\x7F]               # single-byte sequences   0xxxxxxx
    |   [\xC0-\xDF][\x80-\xBF]    # double-byte sequences   110xxxxx 10xxxxxx
    |   [\xE0-\xEF][\x80-\xBF]{2} # triple-byte sequences   1110xxxx 10xxxxxx * 2
    |   [\xF0-\xF7][\x80-\xBF]{3} # quadruple-byte sequence 11110xxx 10xxxxxx * 3 
    ){1,100}                      # ...one or more times
  )
| ( [\x80-\xBF] )                 # invalid byte in range 10000000 - 10111111
| ( [\xC0-\xFF] )                 # invalid byte in range 11000000 - 11111111
/x
END;
function utf8replacer($captures) {
  if ($captures[1] != "") {
    // Valid byte sequence. Return unmodified.
    return $captures[1];
  }
  elseif ($captures[2] != "") {
    // Invalid byte of the form 10xxxxxx.
    // Encode as 11000010 10xxxxxx.
    return "\xC2".$captures[2];
  }
  else {
    // Invalid byte of the form 11xxxxxx.
    // Encode as 11000011 10xxxxxx.
    return "\xC3".chr(ord($captures[3])-64);
  }
}
preg_replace_callback($regex, "utf8replacer", $text);

РЕДАКТИРОВАТЬ:

  • ! Empty (x) будет соответствовать непустым значениям ( «0» считается пустым) .
  • x! = "" будет соответствовать непустым значениям, включая "0" .
  • x! == "" будет соответствовать чему угодно, кроме "" .

x! = "" кажется лучшим один, чтобы использовать в этом случае.

Я также немного ускорил матч. Вместо сопоставления каждого символа отдельно, он сопоставляет последовательности допустимых символов UTF-8.

80
ответ дан 24 November 2019 в 04:36
поделиться

Как насчет iconv:

http://php.net/manual/en/function.iconv.php

Не использовал его внутри самого PHP, но он всегда работал хорошо для меня в командной строке. Вы можете заставить его заменять недопустимые символы.

-1
ответ дан 24 November 2019 в 04:36
поделиться

Итак, правила таковы, что первый октлет UTF-8 имеет высокий бит, установленный в качестве маркера, а затем от 1 до 4 битов, чтобы указать, сколько дополнительных октлетов; тогда для каждого из дополнительных октлетов должны быть установлены два старших бита равными 10.

Псевдо-питон будет выглядеть так:

newstring = ''
cont = 0
for each ch in string:
  if cont:
    if (ch >> 6) != 2: # high 2 bits are 10
      # do whatever, e.g. skip it, or skip whole point, or?
    else:
      # acceptable continuation of multi-octlet char
      newstring += ch
    cont -= 1
  else:
    if (ch >> 7): # high bit set?
      c = (ch << 1) # strip the high bit marker
      while (c & 1): # while the high bit indicates another octlet
        c <<= 1
        cont += 1
        if cont > 4:
           # more than 4 octels not allowed; cope with error
      if !cont:
        # illegal, do something sensible
      newstring += ch # or whatever
if cont:
  # last utf-8 was not terminated, cope

Та же самая логика должна быть переведена в php. Однако неясно, какое удаление нужно делать, когда вы получаете искаженный персонаж.

1
ответ дан 24 November 2019 в 04:36
поделиться
$string = preg_replace('~&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', htmlentities($string, ENT_COMPAT, 'UTF-8'));
3
ответ дан 24 November 2019 в 04:36
поделиться

Если применить utf8_encode() к уже UTF8-строке, она вернет искаженный UTF8-вывод.

Я сделал функцию, которая решает все эти проблемы. Она называется Encoding::toUTF8().

Вам не нужно знать, какая кодировка у ваших строк. Это может быть Latin1 (ISO8859-1), Windows-1252 или UTF8, или строка может иметь их смесь. Encoding::toUTF8() преобразует все в UTF8.

Я сделал это, потому что один сервис выдавал мне данные в беспорядке, смешивая эти кодировки в одной строке.

Использование:

require_once('Encoding.php'); 
use \ForceUTF8\Encoding;  // It's namespaced now.

$utf8_string = Encoding::toUTF8($mixed_string);

$latin1_string = Encoding::toLatin1($mixed_string);

Я включил еще одну функцию, Encoding::fixUTF8(), которая исправит все строки UTF8, которые выглядят искаженными из-за того, что были закодированы в UTF8 несколько раз.

Usage:

require_once('Encoding.php'); 
use \ForceUTF8\Encoding;  // It's namespaced now.

$utf8_string = Encoding::fixUTF8($garbled_utf8_string);

Examples:

echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");
echo Encoding::fixUTF8("FÃÂédÃÂération Camerounaise de Football");
echo Encoding::fixUTF8("Fédération Camerounaise de Football");

will output:

Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football
Fédération Camerounaise de Football

Download:

https://github.com/neitanod/forceutf8

126
ответ дан 24 November 2019 в 04:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: