MySQL, UTF и русские символы

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

MySQL, UTF и русские символы

Сообщение arriah » 28.06.2016 00:00:36

Привет,

знаю, тема избитая, перерыл много чего, но возникли вопросы. надеюсь поможете.

Lazarus 1.6, FPC 3.0.0

Своей софтиной цепляюсь на удаленный сервер с MySQL через MySQL56Connection, CharSet в свойствах установлен UTF8, ибо база данных в UTF8
С этим проблем не возникает, все нормально корректно отображается

Из базы выгребаю html код, который надо распарсить, с этим тоже нет проблем.
Проблема начинается с русскими символами, когда начинаешь их искать в строке..
К примеру получаю строку:
str:=<a href=ссылка>описание ссылки</a> делаю так:
Код: Выделить всё
str1:=copy(str, pos('>',str)+1,pos('</a>',str)-pos('>',str)-2);

Строка как пример, таких строк много и разные
Но результат непонятный, может быть все что угодно, но не то что надо...
Вот тут я первый раз задумался о том в какой кодировке что у меня есть :)
Ладно, это обошел удалением всего до > и после </a>

Ну а дальше вобще непонятно стало, в строке есть слово Источник - и вот по нему мне надо сделать поиск..чтобы не парсить строку со ссылкой на источник...

Код: Выделить всё
if pos('источник',str)>0 then //не обрабатывать


Пофигу мороз - условие не видно, почитал в инете, подключал и lazutf8 и LCL, пользовался и pos и UTF8pos - не помогает...

от нечего делать написал:
Код: Выделить всё
if pos('источник',str)>0 then showmessage('НАШЕЛ!!!!');


сделал выборку из базы около 50 записей сидел тыкал....
результат ошеломляющий - иногда находит слово "Источник" и показывает мне месагу, иногда не находит...заменил pos, на UTF8Pos - Тоже самое

Что делать и куда копать?
arriah
новенький
 
Сообщения: 94
Зарегистрирован: 29.07.2015 16:42:35

Re: MySQL, UTF и русские символы

Сообщение Vadim » 28.06.2016 06:43:26

arriah
Бывает так, что в логике задуманного действия есть ошибка, но с ходу её не видно, потому что действие реализовано сильно сложно. Как пример:
Код: Выделить всё
str1:=copy(str, pos('>',str)+1,pos('</a>',str)-pos('>',str)-2);

Поверьте, сходу и не разберёшься... ;-)
Может быть стоило написать так?
Код: Выделить всё
Var
  p1, p2: intrger;
Begin
...
  p1:= pos('>', str)+1;
  p2:=pos('</a>', str)-p1-2;
  str1:=copy(str, p1, p2);
...
End;

И экспериментами выяснить, а правильные ли позиции символов выдаёт Вам Ваша конструкция. Согласитесь, так как я написал сделать это проще.
arriah писал(а):сделал выборку из базы около 50 записей сидел тыкал....
результат ошеломляющий - иногда находит слово "Источник" и показывает мне месагу, иногда не находит...заменил pos, на UTF8Pos - Тоже самое

А Вы читали описание к функции "pos()"? Поиск регистрозависмый. А у Вас литералы для поиска заданы с маленькой буквы, а ищете Вы слово, которое начинается с большой. Потому и результаты поиска такие интересные. ;-) Попробуйте поиск делать с преобразованием строк к какому либо одному регистру с помощью "AnsiUpperCase()" или "AnsiLowerCase()".
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: MySQL, UTF и русские символы

Сообщение arriah » 28.06.2016 10:29:31

Vadim писал(а):Бывает так, что в логике задуманного действия есть ошибка, но с ходу её не видно, потому что действие реализовано сильно сложно. Как пример:
КОД: ВЫДЕЛИТЬ ВСЁ

Это понятно - тут я только как пример описал. У меня для этого написано функция, которая возвращает строку заключенную между символами, например между <a> и </a>
Источник заключен в параграф <p>Источник: домен.ру</p> - поэтому вытаскивает корректно. Но есть строки, которые <a href=домен.ру>Источник</a>, если его пропарсить тем что есть - останется только слово Источник, а в моем случае, надо вытащить ссылку на этот Источник - поэтому и пытаюсь найти данное слово в тексте.

Vadim писал(а):А Вы читали описание к функции "pos()"? Поиск регистрозависмый. А у Вас литералы для поиска заданы с маленькой буквы, а ищете Вы слово, которое начинается с большой. Потому и результаты поиска такие интересные. Попробуйте поиск делать с преобразованием строк к какому либо одному регистру с помощью "AnsiUpperCase()" или "AnsiLowerCase()".


Конечно читал. И даже где-то натыкался на упоминание что UTF8 регистронезависимый (если неошибаюсь), но как бы там ни было - провел следующий эксперимент:

1. Руками в базе удалил все, оставил слово [Источник]
Результат: не находит. Сверил длины сравнимаемых строк: Источник - 16, [Источник]-18 - оно и понятно, русские символы по два байта.

2. Руками из базы, в той записи, в которой моя софтина находит слово Источник, удалил все, оставил слово [Источник]
Результат: Слово находится, длины слов те же.

Игрался с BOM и без оного, пробовал и UTF8ToAnsi и UTF8Decode|UTF8Encode - все бестолку. Ищет только то. что он сам хочет :((

База данных - это CMC от DLE - там записи все корректные. Для пущей убедительности - проверил настройки MySQL - переменные, сравнения, сами базы - все в UTF8.

Начинаю задумывать о своих умственных способностях и о смысле жизни.
Последний раз редактировалось arriah 28.06.2016 10:51:57, всего редактировалось 1 раз.
arriah
новенький
 
Сообщения: 94
Зарегистрирован: 29.07.2015 16:42:35

Re: MySQL, UTF и русские символы

Сообщение Лекс Айрин » 28.06.2016 10:46:12

arriah писал(а): И даже где-то натыкался на упоминание что UTF8 регистронезависимый (если неошибаюсь),


с чего бы это?
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: MySQL, UTF и русские символы

Сообщение arriah » 28.06.2016 10:51:24

Лекс Айрин писал(а):И даже где-то натыкался на упоминание что UTF8 регистронезависимый (если неошибаюсь),


с чего бы это?

Да без понятия, читал ночью, может не так понял :)

Короче, что-то тут не так:

MySQL отдает все в UTF8. Лазарь так же в UTF8.
Сейчас от безысходности, строку из базы, которая уже в UTF8 перевел в AnsiToUTF8(str) - и все заработало... и кстати поиск регистронезависимый...

В чем прикол?
В том что винда все отображает в cp1251? А посик происходит в DBMemo1?
arriah
новенький
 
Сообщения: 94
Зарегистрирован: 29.07.2015 16:42:35

Re: MySQL, UTF и русские символы

Сообщение Лекс Айрин » 28.06.2016 11:03:13

arriah, скорее, база может отдавать приведенные к одному регистру строки.

arriah писал(а):Сейчас от безысходности, строку из базы, которая уже в UTF8 перевел в AnsiToUTF8(str) - и все заработало...

значит, отдают строки в ansi.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: MySQL, UTF и русские символы

Сообщение arriah » 28.06.2016 11:09:37

SET character_set_results=UTF8 - значит база отдает в UTF-8
Длина слова Источник из базы - 16 символов, насколько я понимаю ansi - Однобайтовая кодировка, значит должно быть 8.

И потом, я и так искал
Код: Выделить всё
pos(UTF8ToAnsi('Источник'),str)>0 then
к результату не приводило, а
Код: Выделить всё
pos('Источник', AnsiToUTF8(str))>0 then

дает правильный результат...

Просто интересно что происходит в мозгах лазаря...
arriah
новенький
 
Сообщения: 94
Зарегистрирован: 29.07.2015 16:42:35

Re: MySQL, UTF и русские символы

Сообщение Лекс Айрин » 28.06.2016 11:20:30

arriah писал(а):дает правильный результат...


То есть, вы пытаетесь перевести в utf8 строку которая уже находится в нем? Конечно у вас ничего не получится.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: MySQL, UTF и русские символы

Сообщение arriah » 28.06.2016 11:26:12

Лекс Айрин писал(а):То есть, вы пытаетесь перевести в utf8 строку которая уже находится в нем? Конечно у вас ничего не получится.


:) Давайте еще раз, по полочкам:

str - приехало из базы, УЖЕ в UTF-8 потому что SET character_set_results=UTF8 (SET CHARACTER SET UTF8 или SET NAMES UTF8) - MySQL 5.6

pos('Источник',str)>0 then - не работе (оба в UTF8)

pos(UTF8ToAnsi('Источник'),str)>0 then - не работает (str в UTF8, а я искомое слово из UTF8 перевожу в Ansi)

pos('Источник', AnsiToUTF8(str))>0 then - работает (str в UTF8, а я его снова перевожу в UTF8)

где логика?
arriah
новенький
 
Сообщения: 94
Зарегистрирован: 29.07.2015 16:42:35

Re: MySQL, UTF и русские символы

Сообщение azsx » 28.06.2016 11:48:48

str - приехало из базы, УЖЕ в UTF-8 потому что SET character_set_results=UTF8 (SET CHARACTER SET UTF8 или SET NAMES UTF8) - MySQL 5.6

так как сам мучаюсь с сохранением страниц в разных кодировках в постгрес рискну с вами не согласиться. От того, что вы сохранили что-то в поле с кодировкой utf-8 еще не сделало этот текст utf-8. То есть для постгреса верно, там может быть и ANSI из базы.
azsx
энтузиаст
 
Сообщения: 959
Зарегистрирован: 16.11.2015 06:38:32

Re: MySQL, UTF и русские символы

Сообщение arriah » 28.06.2016 12:03:55

azsx писал(а):так как сам мучаюсь с сохранением страниц в разных кодировках в постгрес рискну с вами не согласиться. От того, что вы сохранили что-то в поле с кодировкой utf-8 еще не сделало этот текст utf-8. То есть для постгреса верно, там может быть и ANSI из базы.

В БД не я пишу, а база заполняется из CMC DLE... но если вы правы, я сейчас проверю :)

Добавлено спустя 12 минут 33 секунды:
Вобще ничего не понял...

Не делал никаких изменией в БД, все заработало и даже pos('',str) - без всяких переконвертаций...

Я отказываюсь что-либо понимать.

Черте что...
arriah
новенький
 
Сообщения: 94
Зарегистрирован: 29.07.2015 16:42:35

Re: MySQL, UTF и русские символы

Сообщение Лекс Айрин » 28.06.2016 12:22:40

вот прототипы:
Код: Выделить всё
Function  Pos (const Substr : RawByteString; const Source : RawByteString) : SizeInt;
Function  Pos (c : AnsiChar; const s : RawByteString) : SizeInt;   


Где Substr -- это искомая строка, а source строка в которой ищут.

arriah писал(а):pos(UTF8ToAnsi('Источник'),str)>0 then


Насколько я помню, UTF8ToAnsi работает с глюками -- попробуйте заменить на UTF8ToCP1251
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: MySQL, UTF и русские символы

Сообщение resident » 28.06.2016 22:23:00

azsx писал(а):От того, что вы сохранили что-то в поле с кодировкой utf-8 еще не сделало этот текст utf-8

Странно, а у меня постгрес ругается, если (как бы сказать?) невалидный UTF-8 символ хочу записать.

arriah писал(а):Я отказываюсь что-либо понимать.
Черте что...

У меня тоже был типа того прикол. Не работал запрос постгрес. Я уж и тут тему открыл, и в инете искал и доки по постгресу. За целый день мозги отлетели, но я таки изменил запрос, что он заработал. В итоге на следующий день, все само заработало! Так же мной был упомянут черт :mrgreen:
viewtopic.php?f=31&t=11131
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: MySQL, UTF и русские символы

Сообщение azsx » 29.06.2016 02:49:30

и у меня ругался на некорентные символы, я их даже находил. Потом начал сперва преобразовывать получаемую строку http://wiki.freepascal.org/Theodp, затем через парамс в запрос передавать
http://www.freepascal.ru/forum/viewtopi ... 95&t=10870
Но лучше не стало, внутри если эту строку с таблицы в таблицу перевести - надо преобразовывать в utf8. Я так подозреваю, что если бы я изначально взял utf-32 то проблем бы не было. Но ваще я в кодировках ничего не понимаю.
зы
Просто напомню, в том числе и вы мне помогли в той теме :)
azsx
энтузиаст
 
Сообщения: 959
Зарегистрирован: 16.11.2015 06:38:32

Re: MySQL, UTF и русские символы

Сообщение Лекс Айрин » 29.06.2016 09:23:47

resident писал(а):В итоге на следующий день, все само заработало!

В следующий раз попробуйте перекомпиляцию с очисткой. Возможно, речь о рассинхронизации проекта и его откомпилированных библиотек.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 254

Рейтинг@Mail.ru