Форум: "Начинающим";
Текущий архив: 2010.02.14;
Скачать: [xml.tar.bz2];
ВнизUTF-8 Найти похожие ветки
← →
ford © (2009-11-27 13:27) [0]Здравствуйте!
как на дельфи автоматически определить, что текст в кодировке UTF-8 ?
в инете нашел что есть такая славная функция
как function DetectUTF8Encoding(const s : UTF8String): TEncodeType;
в модуле WideStrUtils.pas
но в своем Delphi 7
я такого модуля не нашел :(
← →
Игорь Шевченко © (2009-11-27 13:36) [1]
> как на дельфи автоматически определить, что текст в кодировке
> UTF-8
никак
← →
ford © (2009-11-27 13:47) [2]ну почему никак ....
я вот написал такую функциюFunction UTF8Check(src:TStrings):Boolean;
var i,j,RCount,ACount:Integer;
s:String;
Begin
RCount:=0; ACount:=0;
for i:=0 to src.Count-1 do
Begin
s:=src[i];
for j:=1 to Length(s) do
Begin
Inc(ACount);
if (Ord(s[j])>=192) and (Ord(s[j])<=255) Then Inc(RCount);
End;
end;
if ((rCount*100)/acount)<20 Then result:=true
Else result:=false;
End;
в принципе определяется что там UTF8
хотя конечно это не 100%
но работает
а вот подскажите, я поставил менее 20% должны встречаться русские букавки :) честно, поставил от балды, может кто подскажет какой процент наличия русских букв относительно всего текста может с более менее нормальной долей вероятности сказать что этот текст в utf8 ?
понятно что моя функция на тексте
"privet vasya" выдаст что это UTF8 :( может что то еще нужно проверять не просто что это английские буквы а еще и что много "P" и "?" ?
← →
clickmaker © (2009-11-27 13:49) [3]на паскаль сам переводи
BOOL IsUTF8(LPBYTE pbBuff, LONG cb)
{
BOOL fASCII;
int i, nb, curr;
BYTE b;
BOOL result = FALSE;
if (cb == 0) return result;
fASCII = TRUE;
curr = 0;
while (curr < cb)
{
nb = 0;
b = pbBuff[curr];
if ((b & 0x80) != 0)
{
fASCII = FALSE;
if ((b & 0xc0) == 0x80) return result;
else if ((b & 0xe0) == 0xc0) nb = 1;
else if ((b & 0xf0) == 0xe0) nb = 2;
else if ((b & 0xf8) == 0xf0) nb = 3;
else if ((b & 0xfc) == 0xf8) nb = 4;
else if ((b & 0xfe) == 0xfc) nb = 5;
else return result;
if (curr + nb >= cb) return result;
for (i = 1; i <= nb; i++)
{
if ((pbBuff[i + curr] & 0xC0) != 0x80) return result;
}
}
curr += nb + 1;
}
result = !fASCII;
return result;
}
← →
ford © (2009-11-27 14:10) [4]а пояснить логику можно??
← →
Медвежонок Пятачок © (2009-11-27 14:17) [5]Решение в лоб.
var s : string;
begin
s := "мама мыла раму";
//s := AnsiToUtf8(s);
if AnsiToUtf8(Utf8ToAnsi(s)) <> s then ShowMessage("Либо не в утф, либо нет не-анси символов")
← →
clickmaker © (2009-11-27 14:31) [6]> [4] ford © (27.11.09 14:10)
> а пояснить логику можно??
логика там несложная.
в утф-8 каждый символ может занимать от 1 до 6 байт. Если значение байта лежит за пределами кодировки ascii ((b & 0x80) != 0), то проверяем значение на совпадение с некими масками, которые с достаточной долей вероятности говорят о том, что это утф.
При этом в каждом байте также установлены биты, которые говорят, что этот байт не является последним (nb = 1...nb = 5).
← →
ford © (2009-11-27 16:04) [7]
> Решение в лоб.
прикольное решение
для больших текстов не подходит но для маленьких вполне :)
> clickmaker © (27.11.09 14:31) [6]
спасибо, теперь понятно что там делается :)
← →
Омлет © (2009-11-30 18:20) [8]> [7] ford © (27.11.09 16:04)
> для больших текстов не подходит но для маленьких вполне
Бери маленький кусок большого текста.
← →
Евгений471 (2009-12-14 11:37) [9]
> while (curr < cb) { nb = 0; b = pbBuff[curr]; if ((b
> & 0x80) != 0) { fASCII = FALSE; if ((b & 0xc0) == 0x80)
> return result; else if ((b & 0xe0) == 0xc0) nb = 1; else
> if ((b & 0xf0) == 0xe0) nb = 2; else if ((b & 0xf8) ==
> 0xf0) nb = 3; else if ((b & 0xfc) == 0xf8) nb = 4; else
> if ((b & 0xfe) == 0xfc) nb = 5; else return result; if
> (curr + nb >= cb) return result; for (i = 1; i <= nb;
> i++) { if ((pbBuff[i + curr] & 0xC0) != 0x80) return
> result; } } curr += nb + 1; } result = !fASCII;
на pascal
function TEncodeClass.FromString(const index: integer;
const s: string): char;
begin
if (index <= 0) or (index > length(s)) then
begin
Result := #0;
exit;
end;
Result := s[index];
end;
function TEncodeClass.IsUtf8(const s: string; const cb:cardinal): boolean;
var
fASCII:boolean;
i, nb, curr:integer;
b:byte;
begin
Result := false;
if cb<=0 then exit;
fASCII := TRUE;
curr := 1;
while (curr < cb) do
begin
nb := 0;
b := ord(FromString(curr,s));
if (b and StrToInt64("0x80")) <> 0 then
begin
fASCII := FALSE;
if (b and StrToInt64("0xc0")) = StrToInt64("0x80") then exit else
if (b and StrToInt64("0xe0")) = StrToInt64("0xc0") then nb := 1 else
if (b and StrToInt64("0xf0")) = StrToInt64("0xe0") then nb := 2 else
if (b and StrToInt64("0xf8")) = StrToInt64("0xf0") then nb := 3 else
if (b and StrToInt64("0xfc")) = StrToInt64("0xf8") then nb := 4 else
if (b and StrToInt64("0xfe")) = StrToInt64("0xfc") then nb := 5 else exit;
if curr + nb >= cb then exit;
for i := 1 to nb do
if (ord(FromString(i+curr,s)) and StrToInt64("0xC0")) <> StrToInt64("0x80") then exit;
end;
inc(curr,nb+1);
end;
Result := not fASCII;
end;
← →
clickmaker © (2009-12-14 11:43) [10]> (b and StrToInt64("0xc0")) = StrToInt64("0x80")
что это??
← →
Евгений471 (2009-12-14 14:57) [11]
> > (b and StrToInt64("0xc0")) = StrToInt64("0x80")что это?
> ?
> StrToInt64("0x80")
числа в 16-ти ричной системе - коды символов.
просто перевел код с C на pascal без изминений, лень было писать коды символов в оригенальном значении.
вот этот код:
BOOL IsUTF8(LPBYTE pbBuff, LONG cb)
{
BOOL fASCII;
int i, nb, curr;
BYTE b;
BOOL result = FALSE;
if (cb == 0) return result;
fASCII = TRUE;
curr = 0;
while (curr < cb)
{
nb = 0;
b = pbBuff[curr];
if ((b & 0x80) != 0)
{
fASCII = FALSE;
if ((b & 0xc0) == 0x80) return result;
else if ((b & 0xe0) == 0xc0) nb = 1;
else if ((b & 0xf0) == 0xe0) nb = 2;
else if ((b & 0xf8) == 0xf0) nb = 3;
else if ((b & 0xfc) == 0xf8) nb = 4;
else if ((b & 0xfe) == 0xfc) nb = 5;
else return result;
if (curr + nb >= cb) return result;
for (i = 1; i <= nb; i++)
{
if ((pbBuff[i + curr] & 0xC0) != 0x80) return result;
}
}
curr += nb + 1;
}
result = !fASCII;
return result;
}
← →
clickmaker © (2009-12-14 15:20) [12]лень писать $80 вместо StrToInt64("0x80") ?
← →
Евгений471 (2009-12-14 17:24) [13]
> лень писать $80 вместо StrToInt64("0x80") ?
яж указал, как есть в исходном - так и написал, кого не устроит вариант - поправить недолго.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2010.02.14;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.005 c