Страницы

Поиск по вопросам

среда, 29 января 2020 г.

('%EF%BB%BF' , '%C2%A0') Что это за символы и как их удалить из url?

#php #строки #utf_8 #unicode


Помогите пожалуйста решить.

1) var_dump('%EF%BB%BF'); //string(3) ""

2) var_dump('%C2%A0'); // string(2) " "


Первый вроде пустая строка,как может быть результат var_dum = string(3) "".

Другого объяснения как юникод я не знаю.Походу эти (utf-8) невидимые символы и есть.

Самый простой вариант 

var_dump(explode('%', 'aaa%EF%BB%BF')[0]);


Но насколько правильно поступать таким образом я не уверен

Если это так то надо учесть что может быть этот пробел под другой кодировкой выглядит
иначе и как можно очистить от него строку ?
    


Ответы

Ответ 1



%EF%BB%BF - BOM - Byte Order Mark для Unicode. %C2%A0 - Utf-8 non breaking space В таком формате Вы видите их в URL, в php же они приходят как: %EF%BB%BF => pack("CCC",0xef,0xbb,0xbf) %C2%A0 => pack("CC",0xc2,0xa0) Ну, или проще: urldecode('%C2%A0') Именно так их и нужно проверять. В этом вашем примере в исходной строке все символы печатные: var_dump(explode('%', 'aaa%EF%BB%BF')[0]); Удалить можно так: function removeBOM($str=""){ if(substr($str, 0,3) == pack("CCC",0xef,0xbb,0xbf)) { $str=substr($str, 3); } return $str; } И так: $str = preg_replace('/\xA0/u', '', 'A'.pack("CC",0xc2,0xa0).'B'); Удалить все непечатаемые символы: $str = preg_replace('/[^[:print:]]/', '', $str); Demo var_dump(preg_replace('/\xA0/u', '', urldecode("Word%C2%A0Word"))); // WordWord var_dump(preg_replace('/[^[:print:]]/', '', urldecode("%EF%BB%BFWord%C2%A0Word"))); // WordWord

Ответ 2



Перевод этого ответа 7-битный ASCII? Если вы вдруг оказались в 1963 году, и всего лишь хотите использовать печатные символы 7-битного ASCII, то нужно всего лишь удалить все символы в диапазоне кодов 0-31 и 127-255: $string = preg_replace('/[\x00-\x1F\x7F-\xFF]/', '', $string); 8-битный расширенный ASCII? В 1963 вам не понравилось и вы переместились в восьмидесятые и столкнулись с 8-битным ASCII, в котором символы 128-255 являются обычными, отображаемыми, символами. Тогда вам нужно лишь слегка скорректировать строку замены и удалять символы 0-31 и 127: $string = preg_replace('/[\x00-\x1F\x7F]/', '', $string); UTF-8? Добро пожаловать в 21 век! Если ваша строка является строкой UTF-8, то вам придется использовать модификатор \u: $string = preg_replace('/[\x00-\x1F\x7F]/u', '', $string); Вы просто удаляете символы 0-31 и 127. Данная конструкция будет работать как для UTF-8, так и для 8-битного ASCII, так как второе является подмножеством первого и они обе имеют одни и те же диапазоны управляющих символов. Откровенно говоря, такая конструкция будет работать и без /u, но он сделает вашу жизнь легче, если вам будет необходимо удалять и какие либо другие символы... Если же вы имеете дело в Unicode, то в нем очень много непечатных символов, но давайте рассмотрим один, самый часто употребимый: NO-BREAK SPACE (U+00A0) В строке UTF-8, он может быть представлен как 0xC2A0. Соответственно вам будет необходимо искать и удалять эту последовательность символов, но, если вы использовали модификатор /u, вы можете просто указать \xA0: $string = preg_replace('/[\x00-\x1F\x7F\xA0]/u', '', $string); Бонус: а что если str_replace? preg_replace крайне эффективен, но если вам необходимо обработать большое количество текста, то более производительным будет использовать str_replace с указанием ему массива символов: //задаем массив, который будем использовать во всех своих операциях замены $badchar=array( // Управляющие символы chr(0), chr(1), chr(2), chr(3), chr(4), chr(5), chr(6), chr(7), chr(8), chr(9), chr(10), chr(11), chr(12), chr(13), chr(14), chr(15), chr(16), chr(17), chr(18), chr(19), chr(20), chr(21), chr(22), chr(23), chr(24), chr(25), chr(26), chr(27), chr(28), chr(29), chr(30), chr(31), // Непечатные символы chr(127) ); //Удаляем нежелательные символы $str2 = str_replace($badchar, '', $str); Интуитивно кажется, что данный подход будет работать сильно быстрее, но давайте проведем тесты. Создадим набор тестовых строк различной длины и содержания и проверим скорость работы (использовался PHP 7.0.12): 2 chars str_replace 5.3439ms preg_replace 2.9919ms preg_replace is 44.01% faster 4 chars str_replace 6.0701ms preg_replace 1.4119ms preg_replace is 76.74% faster 8 chars str_replace 5.8119ms preg_replace 2.0721ms preg_replace is 64.35% faster 16 chars str_replace 6.0401ms preg_replace 2.1980ms preg_replace is 63.61% faster 32 chars str_replace 6.0320ms preg_replace 2.6770ms preg_replace is 55.62% faster 64 chars str_replace 7.4198ms preg_replace 4.4160ms preg_replace is 40.48% faster 128 chars str_replace 12.7239ms preg_replace 7.5412ms preg_replace is 40.73% faster 256 chars str_replace 19.8820ms preg_replace 17.1330ms preg_replace is 13.83% faster 512 chars str_replace 34.3399ms preg_replace 34.0221ms preg_replace is 0.93% faster 1024 chars str_replace 57.1141ms preg_replace 67.0300ms str_replace is 14.79% faster 2048 chars str_replace 94.7111ms preg_replace 123.3189ms str_replace is 23.20% faster 4096 chars str_replace 227.7029ms preg_replace 258.3771ms str_replace is 11.87% faster 8192 chars str_replace 506.3410ms preg_replace 555.6269ms str_replace is 8.87% faster 16384 chars str_replace 1116.8811ms preg_replace 1098.0589ms preg_replace is 1.69% faster 32768 chars str_replace 2299.3128ms preg_replace 2222.8632ms preg_replace is 3.32% faster Замеры производились для 10.000 итераций. Тут очень интересно посмотреть на относительные различия. Для строк длиной до 512 символов со значительным отрывом побеждает preg_replace. В диапазоне 1-8kb разница нивелируется. Интересный результат, не правда ли? Но в любом случае не стоит всецело полагаться на мои тесты, так как на ваших конкретных данных все может быть ровно наоборот.

Ответ 3



На самом деле, посмотрите в сторону расширения INTL Там есть, например, такое IntlChar::isprint — Проверяет, является ли симвом отображаемым

Комментариев нет:

Отправить комментарий