UTF8 and per char string accessing

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

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

UTF8 and per char string accessing

Сообщение FedeX » 18.10.2009 11:40:03

Здравствуйте.
Я так понимаю, что обращаться посимвольно к строке в кодировке UTF8 стандартным образом нельзя. Верно?
Вопрос в том есть ли какие-нибудь быстрые функции для этого? Просто задача такая - строк очень много, все в UTF8, во всех надо анализировать каждый символ и в зависимости от этого разрезать/склеивать эти строки. И в конечном итоге они опять должны быть в UTF8 для использования в Canvas.TextOut (я так понимаю он теперь тоже только UTF8 понимает?). Очень не хотелось бы несколько тысяч а то и миллионов строк гонять в WideString и обратно (учитывая что делаться это должно довольно часто). Но пока ничего кроме этого в голову не приходит.. :(
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Re: UTF8 and per char string accessing

Сообщение Odyssey » 18.10.2009 12:47:00

Конечно есть. Например в составе fpGUI есть модуль fpg_stringutils.pas, в котором есть функция UTF8CharAtByte. Она позволяет ускорить последовательный перебор символов в UTF-8 строке за счет "сохранения" позиции конкретного символа в байтах.
Код: Выделить всё
function  UTF8CharAtByte(const s: string; const BytePos: integer; out aChar: string): integer;
  s -строка в которой ищем
  BytePos - позиция символа в байтах, для первого символа = 1
  aChar - символ на этой позиции
  Возвращает - позицию следующего символа в байтах.

Используется примерно так:
Код: Выделить всё
bytepos = 1;
while bytepos <= Length(str) do
begin
  bytepos := UTF8CharAtByte(str, bytepos, ch);
  // Здесь в строке ch содержится очередной символ строки str. 
end;

Если эта функция покажется неудобной, исходный код модуля даёт представление о механизме работы, и можно написать своой функционал под конкретную задачу.

P.S. под "сохранением" позиции имею в виду то, что не приходится каждый раз просматривать строку с начала
Odyssey
энтузиаст
 
Сообщения: 580
Зарегистрирован: 29.11.2007 17:32:24

Re: UTF8 and per char string accessing

Сообщение FedeX » 18.10.2009 13:07:13

О! Это уже гораздо лучше. :D Спасибо!
Только, наверно, aChar это тоже UTF-8... Ну да ладно, главное уже есть куда копать, а то гугл ничего не давал..
Кстати там функции (судя по комментариям) частично скопированы из LCLProc.pas, а уже в нём я нашол ещё больше функций для работы с UTF8 посимвольно.
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир

Re: UTF8 and per char string accessing

Сообщение Sergei I. Gorelkin » 18.10.2009 14:51:17

Ты бы задачу поподробнее описал. В куче случаев все можно оптимизировать и посимвольный доступ просто не нужен.
Например, если символ, который нужно искать и по которому разрезать - пробел, или что угодно с кодом меньше 128, то можно и нужно работать в точности так же, как с ansistring. Т.е. находится байтовый индекс пробела, а какому индексу символа он соответствует - не так уж и важно.
Аватара пользователя
Sergei I. Gorelkin
энтузиаст
 
Сообщения: 1405
Зарегистрирован: 24.07.2005 14:40:41
Откуда: Зеленоград

Re: UTF8 and per char string accessing

Сообщение FedeX » 18.10.2009 16:06:22

Спасибо, это понятно, я знаю что до кода 128 UTF8 совместим ANSI, но здесь ситуация именно такая, что нужно для любых символов. Благодарю всех!
Аватара пользователя
FedeX
постоялец
 
Сообщения: 422
Зарегистрирован: 27.03.2006 09:25:34
Откуда: украина, житомир


Вернуться в Lazarus

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 28

Рейтинг@Mail.ru
cron