|
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
|
|||
---|---|---|---|
#18+
Столкнулся с вот какой заковыкой... С сервера получаю JSON, это подгружаемые фрагменты для мобильной версии сайта. Сам сайт в UTF-8. Затем полученное пропускаю через json_decode в массив и элементы массива запихиваю в базу. База тоже в UTF-8. Всё хорошо, но иногда попадаются какие-то инородные символы, и тогда СУБД вертает ошибки такого вида: Код: sql 1. 2.
Первые два байта \xF0\x9F одинаковы во всех сообщениях (из тех, что попадались, по крайней мере), вторые два - варьируются. Собственно, вопрос. Есть какой-то не слишком сложный способ оставить в строке текста только однобайтовые символы и utf-8, а остальное заменить вопросиками или, накрайняк, вырезать? preg_replace, конечно, вариант, но как правильно задать ограничения в регулярке - не соображу. ... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2016, 19:48 |
|
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
|
|||
---|---|---|---|
#18+
vkle, вполне себе корректные четырёхбайтовые юникодные UTF8 🐾 https://www.compart.com/en/unicode/U 1F43E 🚗 https://www.compart.com/en/unicode/U 1F697 PS в MySQL для utf-8 есть трёхбайтовые и четырёхбайтовые кодировки utf8mb3 и utf8mb4 ... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2016, 21:43 |
|
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
|
|||
---|---|---|---|
#18+
Изопропил, вона чё... Видимо, завис я на двухбайтовых utf-8 :) Так понимаю, в моём случае достаточно будет сменить в мускуле utf8_unicode_ci на utf8mb4_unicode_ci. Тогда вопрос снимается, спасибо большое! ... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2016, 22:11 |
|
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
|
|||
---|---|---|---|
#18+
vklepreg_replace, конечно, вариант Код: php 1.
... |
|||
:
Нравится:
Не нравится:
|
|||
07.11.2016, 22:13 |
|
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
|
|||
---|---|---|---|
#18+
vkleТак понимаю, в моём случае достаточно будет сменить в мускуле utf8_unicode_ci на utf8mb4_unicode_ci. Увы и ах, поспешил обрадоваться. Установка кодировок и таблицы и полей в utf8mb4_unicode_ci не возымела положительного действия. Может, мускуль кажет в сообщении об ошибке не на конкретный проблемный символ, а на начало строки, имеющей проблемные коды? Если так, то эти \xF0\x9F** просто ввели меня в заблуждение и вопрос следует как-то иначе ставить. Кстати, поглядев ошибки, обнаружил ещё и такое: Код: sql 1.
Тут от соседнего символа \xE2 ещё торчит... Так что, вопрос о замене не-ютф-8 остаётся в силе. Изопропил Код: php 1.
Выражение написать не проблема. Проблема узнать (или осознать) границы диапазонов для подмены. Не настолько силён в юникодах, но подозреваю, что таким вот образом вряд ли удастся правильно или коректно выпилить непотребное. Или надо быть достаточно сильным специалистом по юникодам, коим я не являюсь. Может быть, даже стОит переформулировать исходную задачу как-то так: убрать из строки всё "неудобоваримое для мускуля в utf8". ... |
|||
:
Нравится:
Не нравится:
|
|||
08.11.2016, 00:20 |
|
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
|
|||
---|---|---|---|
#18+
vkle, 4-х байтовые выпиливаются согласно спецификации utf-8 \xE2 - - 1110xxxx это трёхбайтовые, выпиливаются соответственно "([\xe0-\xef]..)" utf-8 не так сложен. ... |
|||
:
Нравится:
Не нравится:
|
|||
08.11.2016, 01:07 |
|
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
|
|||
---|---|---|---|
#18+
vkle. Установка кодировок и таблицы и полей в utf8mb4_unicode_ci не возымела положительного действия нужно ещё чтоб соединение с базой использовало charset=utf8mb4 проверил, работает (PDO) phpmyadmin тож работает ... |
|||
:
Нравится:
Не нравится:
|
|||
08.11.2016, 01:48 |
|
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
|
|||
---|---|---|---|
#18+
Изопропилсоединение с базойТьхутэ, забыл совсем про него... Спать надо по ночам, однако, а не косяки отлаживать... Поправил - есть контакт! Изопропил\xE2 - - 1110xxxx это трёхбайтовые, выпиливаются соответственно "([\xe0-\xef]..)"Да, но, если какой-то \xe0 окажется не первым байтом символа, а, скажем, вторым байтом двухбайтового... Тогда получится, что такой прямой заменой порюхаются два символа. Сложность вижу не столько в замене, сколько в определении правильного диапазона байтов в строке для замены, позиции начала и конца. Скажем, первый символ может быть в один байт, второй - три, третий - два... Сам юникод так построен, что символы у него переменной длины. Так понимаю, что если проходить строчку с начала, распознавая каждый байт - то можно находить и каждый отдельный символ, какой диапазон байт в строке он занимает. Регексп прикладывает шаблон, каждый раз сдвигая его на одну позицию в строке. Совпал первый байт - проверяется второй, потом третий. Если начало шаблона попало, скажем на второй байт символа или на третий, а следующие два совпали... Фигня получается. Не? ... |
|||
:
Нравится:
Не нравится:
|
|||
08.11.2016, 03:07 |
|
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
|
|||
---|---|---|---|
#18+
vkle, не будет фигни, \xe0 не может оказаться вторым, второй-четвёртый всегда в диапазоне \x80-\xb0 UTF-8 - все варианты: Код: plaintext 1. 2. 3. 4.
PS как видно из чертежа, по строке можно двигаться и назад ... |
|||
:
Нравится:
Не нравится:
|
|||
08.11.2016, 09:22 |
|
|
start [/forum/topic.php?fid=23&fpage=39&tid=1460866]: |
0ms |
get settings: |
10ms |
get forum list: |
14ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
31ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
others: | 13ms |
total: | 140ms |
0 / 0 |