Удалить не-utf8 символы из строки - PullRequest
96 голосов
/ 09 сентября 2009

У меня проблема с удалением не-utf8 символов из строки, которые отображаются неправильно. Символы похожи на это 0x97 0x61 0x6C 0x6F (шестнадцатеричное представление)

Как лучше всего их удалить? Регулярное выражение или что-то еще?

Ответы [ 15 ]

2 голосов
/ 25 июня 2015

От недавнего патча до модуля JSON-анализатора Drupal Feeds:

//remove everything except valid letters (from any language)
$raw = preg_replace('/(?:\\\\u[\pL\p{Zs}])+/', '', $raw);

Если вы обеспокоены тем, да, он сохраняет пробелы в качестве допустимых символов.

сделал то, что мне было нужно. Он удаляет широко распространенные в настоящее время эмодзи-символы, которые не вписываются в набор символов utf8 MySQL и которые приводят к таким ошибкам, как «SQLSTATE [HY000]: общая ошибка: 1366 Неверное строковое значение».

Подробнее см. https://www.drupal.org/node/1824506#comment-6881382

1 голос
/ 08 февраля 2013

Чтобы удалить все символы Unicode за пределами базовой языковой плоскости Unicode:

$str = preg_replace("/[^\\x00-\\xFFFF]/", "", $str);
1 голос
/ 09 сентября 2009

Таким образом, правила таковы, что первый октлет 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. Тем не менее, неясно, какой вид зачистки следует выполнять после того, как вы получите уродливого персонажа.

0 голосов
/ 12 декабря 2013

Немного отличается от вопроса, но я использую HtmlEncode (string),

псевдокод здесь

var encoded = HtmlEncode(string);
encoded = Regex.Replace(encoded, "&#\d+?;", "");
var result = HtmlDecode(encoded);

вход и выход

"Headlight\x007E Bracket, &#123; Cafe Racer<> Style, Stainless Steel 中文呢?"
"Headlight~ Bracket, &#123; Cafe Racer<> Style, Stainless Steel 中文呢?"

Я знаю, что это не идеально, но делает работу за меня.

0 голосов
/ 09 сентября 2009

Как насчет iconv:

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...