powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / [PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
10 сообщений из 10, страница 1 из 1
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
    #39342921
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Столкнулся с вот какой заковыкой...

С сервера получаю JSON, это подгружаемые фрагменты для мобильной версии сайта. Сам сайт в UTF-8. Затем полученное пропускаю через json_decode в массив и элементы массива запихиваю в базу. База тоже в UTF-8. Всё хорошо, но иногда попадаются какие-то инородные символы, и тогда СУБД вертает ошибки такого вида:
Код: sql
1.
2.
Incorrect string value: '\xF0\x9F\x90\xBE</...' for column .....
Incorrect string value: '\xF0\x9F\x9A\x97\xF0\x9F...' for column .....


Первые два байта \xF0\x9F одинаковы во всех сообщениях (из тех, что попадались, по крайней мере), вторые два - варьируются.

Собственно, вопрос. Есть какой-то не слишком сложный способ оставить в строке текста только однобайтовые символы и utf-8, а остальное заменить вопросиками или, накрайняк, вырезать?

preg_replace, конечно, вариант, но как правильно задать ограничения в регулярке - не соображу.
...
Рейтинг: 0 / 0
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
    #39342977
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkle,

вполне себе корректные четырёхбайтовые юникодные UTF8

🐾 https://www.compart.com/en/unicode/U 1F43E
🚗 https://www.compart.com/en/unicode/U 1F697

PS в MySQL для utf-8 есть трёхбайтовые и четырёхбайтовые кодировки utf8mb3 и utf8mb4
...
Рейтинг: 0 / 0
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
    #39342992
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил, вона чё... Видимо, завис я на двухбайтовых utf-8 :)
Так понимаю, в моём случае достаточно будет сменить в мускуле utf8_unicode_ci на utf8mb4_unicode_ci.
Тогда вопрос снимается, спасибо большое!
...
Рейтинг: 0 / 0
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
    #39342994
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vklepreg_replace, конечно, вариант
Код: php
1.
preg_replace("([\xf0-\xf7]...)", "?", 
...
Рейтинг: 0 / 0
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
    #39343025
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkleТак понимаю, в моём случае достаточно будет сменить в мускуле utf8_unicode_ci на utf8mb4_unicode_ci.
Увы и ах, поспешил обрадоваться. Установка кодировок и таблицы и полей в utf8mb4_unicode_ci не возымела положительного действия. Может, мускуль кажет в сообщении об ошибке не на конкретный проблемный символ, а на начало строки, имеющей проблемные коды? Если так, то эти \xF0\x9F** просто ввели меня в заблуждение и вопрос следует как-то иначе ставить.

Кстати, поглядев ошибки, обнаружил ещё и такое:
Код: sql
1.
Incorrect string value: '\xF0\x9F\x98\xB0 \xE2...' for


Тут от соседнего символа \xE2 ещё торчит...

Так что, вопрос о замене не-ютф-8 остаётся в силе.


Изопропил
Код: php
1.
preg_replace("([\xf0-\xf7]...)", "?", 

Выражение написать не проблема. Проблема узнать (или осознать) границы диапазонов для подмены. Не настолько силён в юникодах, но подозреваю, что таким вот образом вряд ли удастся правильно или коректно выпилить непотребное. Или надо быть достаточно сильным специалистом по юникодам, коим я не являюсь.

Может быть, даже стОит переформулировать исходную задачу как-то так: убрать из строки всё "неудобоваримое для мускуля в utf8".
...
Рейтинг: 0 / 0
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
    #39343032
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkle,

4-х байтовые выпиливаются согласно спецификации utf-8

\xE2 - - 1110xxxx
это трёхбайтовые, выпиливаются соответственно "([\xe0-\xef]..)"

utf-8 не так сложен.
...
Рейтинг: 0 / 0
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
    #39343034
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkle. Установка кодировок и таблицы и полей в utf8mb4_unicode_ci не возымела положительного действия
нужно ещё чтоб соединение с базой использовало charset=utf8mb4

проверил, работает (PDO)
phpmyadmin тож работает
...
Рейтинг: 0 / 0
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
    #39343039
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропилсоединение с базойТьхутэ, забыл совсем про него... Спать надо по ночам, однако, а не косяки отлаживать... Поправил - есть контакт!


Изопропил\xE2 - - 1110xxxx
это трёхбайтовые, выпиливаются соответственно "([\xe0-\xef]..)"Да, но, если какой-то \xe0 окажется не первым байтом символа, а, скажем, вторым байтом двухбайтового... Тогда получится, что такой прямой заменой порюхаются два символа. Сложность вижу не столько в замене, сколько в определении правильного диапазона байтов в строке для замены, позиции начала и конца. Скажем, первый символ может быть в один байт, второй - три, третий - два... Сам юникод так построен, что символы у него переменной длины. Так понимаю, что если проходить строчку с начала, распознавая каждый байт - то можно находить и каждый отдельный символ, какой диапазон байт в строке он занимает. Регексп прикладывает шаблон, каждый раз сдвигая его на одну позицию в строке. Совпал первый байт - проверяется второй, потом третий. Если начало шаблона попало, скажем на второй байт символа или на третий, а следующие два совпали... Фигня получается. Не?
...
Рейтинг: 0 / 0
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
    #39343131
Фотография Изопропил
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
vkle,

не будет фигни, \xe0 не может оказаться вторым, второй-четвёртый всегда в диапазоне \x80-\xb0

UTF-8 - все варианты:
Код: plaintext
1.
2.
3.
4.
0xxxxxxx   
110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

PS как видно из чертежа, по строке можно двигаться и назад
...
Рейтинг: 0 / 0
[PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
    #39343286
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Изопропил, чертёж годный, многое проясняет. Спасибо!
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / [PHP] Как оставить в строке только UTF-8 и однобайтовые символы?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]