![]() |
|
|
|||||||
| Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
![]() |
|
|
Опции темы | Поиск в этой теме | Опции просмотра |
|
#1
|
|||
|
|||
|
Добрый день. Есть функция выбора кодовой страницы
Код:
function FindCharSet(const Data:string):integer;
const (*это в общем не нужно*)
CodePages: array[0..10] of string = ('utf-8','utf-16','windows-1251','koi8-r','iso-8859-1',
'iso-8859-15','windows-1252','iso-8859-2','iso-8859-3','iso-8859-4','iso-8859-5');
var Pos1,Pos2:integer; CharSet:string;
begin
Pos1:=PosEx('charset=',Data,1);
Pos2:=PosEx('>',Data,Pos1);
CharSet:=Copy(Data, Pos1,(Pos2-Pos1+1)); (*выделяем чарсет из страницы*)
if Pos1 > 0 then (*если чарсет есть тогда*)
begin
if True then (*если в чарсет нет указания на кодировку страницы, принудительно назначить 1251*)
begin
Result:=1251;
end
else (*когда номер страницы указан*)
begin
if PosEx('utf-8',CharSet,1) > 0 then Result:=65001;
if PosEx('utf-16',CharSet,1) > 0 then Result:=65001;
if PosEx('windows-1251',CharSet,1) > 0 then Result:=1251;
if PosEx('windows-1252',CharSet,1) > 0 then Result:=1252;
if PosEx('koi8-r',CharSet,1) > 0 then Result:=20866;
if PosEx('iso-8859-1',CharSet,1) > 0 then Result:=28591;
if PosEx('iso-8859-2',CharSet,1) > 0 then Result:=28592;
if PosEx('iso-8859-3',CharSet,1) > 0 then Result:=28593;
if PosEx('iso-8859-4',CharSet,1) > 0 then Result:=28594;
if PosEx('iso-8859-5',CharSet,1) > 0 then Result:=28595;
if PosEx('iso-8859-15',CharSet,1) > 0 then Result:=28605;
end;
end
else (когда чарсета нет, присваиваем принудительно)
begin
Result:=1251;
end;
end;Внимание!! Вопрос: Как покороче написать if True then если использовать массив строк, то прийдется лепить излишне сложный код, поскольку есть варианты: charset=windows-1251" charset="windows-1251" charset='windows-1251' из этого нужно выделить windows-1251(к примеру) если помножить на число кодировок получается громоздко. нет ли какого фокуса чтоб написать покороче |
|
#2
|
|||
|
|||
|
regexp? )))
|
|
#3
|
||||
|
||||
|
завести 2 массива charset[]: String и codepage[]: Integer и через
Код:
function AnsiIndexText(const AText: string; const AValues: array of string): Integer; |
|
#4
|
||||
|
||||
|
Ассоциативный контейнер.
Код:
codepage := list.indexof(переменная с текстом кодировки);
if codepage = -1 then
showmessage('неизвестная кодировка');Цитата:
можно один TStrings к примеру. |
|
#5
|
|||
|
|||
|
это все хорошо, особенно про AnsiIndexText. все это уже используется
но чтоб это применить нужно точно выявить строку с указание кодировки, к примеру windows-1251, что не так то просто с учетом вариантов charset=windows-1251" charset="windows-1251" charset='windows-1251' как сделать простым код выделения указания кодировки, вот о чем вопрос |
|
#6
|
||||
|
||||
|
Цитата:
Код:
Caption:=StringReplace(Caption, '''', '', [rfReplaceAll, rfIgnoreCase]); Caption:=StringReplace(Caption, '"', '', [rfReplaceAll, rfIgnoreCase]); |
|
#7
|
|||
|
|||
|
немного сложнее, на самом деле
charset=windows-1251" charset="windows-1251" charset='windows-1251' или вообще charset=koi8-r" http-equiv="content-type" /> или еще длиннее может запустить цикл FOR с PosEX внутри и подстановкой в цикле значения кодировки из массива? если есть хоть одно совпадение, тогда ДА, если ни одного тогда НЕТ(это выход функции)??? или есть что по прямее, что то чего Я пока еще не знаю? |
|
#8
|
||||
|
||||
|
проще сразу искать одинарную кавычку или двойную в найденной строке charset=... и делать обрезание по этой позиции.
|
|
#9
|
||||
|
||||
|
Код:
function FindCharSet(const Data:string):integer;
const
CodePages: array[0..10] of string = ('windows-1251','utf-8','utf-16','windows-1252',
'koi8-r','iso-8859-1','iso-8859-2','iso-8859-3','iso-8859-4','iso-8859-5','iso-8859-15');
ResArray: array[0..10] of Word = (1251,65001,65001,1252,20866,28591,28592,28593,
28594,28595,28605);
var APos:integer; CharSet:string;
begin
Result:=Pos('charset=',Data);
APos:=PosEx('>',Data,Result);
CharSet:=Copy(Data, Result,(APos-Result+1));
if Result > 0 then
for Result := Length(CodePages)-1 downto 0 do
if Pos(CodePages[Result],CharSet) > 0 then
Break;
Result := ResArray[Result];
end;![]() |
| Этот пользователь сказал Спасибо BBBCat за это полезное сообщение: | ||
Pcrepair (12.03.2013)
| ||
|
#10
|
|||
|
|||
|
только один вопрос:
использование result в качестве переменной по ходу выполнения функции это точно правильно? или может лучше назначить переменные а result использовать только в конце, в момент присвоения результата? |
|
#11
|
||||
|
||||
|
Ну дык надо было сократить, вот я и постарался
Возможно использование Result - это моветон, но неприятностей это не принесёт. Да и вообще-то компилятор Delphi вечно лается, что у вас объявлена переменная, но она нигде не используется, а у самих Result почти не используется ![]() |
|
#12
|
||||
|
||||
|
Сорри, обнаружил баг - цикл нужно сделать не до 0, а до 1.
Ну и выкинул кое-что...Код:
function FindCharSet(const Data:string):integer;
const
CodePages: array[0..10] of string = ('windows-1251','utf-8','utf-16','windows-1252',
'koi8-r','iso-8859-1','iso-8859-2','iso-8859-3','iso-8859-4','iso-8859-5','iso-8859-15');
ResArray: array[0..10] of Word = (1251,65001,65001,1252,20866,28591,28592,28593,
28594,28595,28605);
var CharSet:string;
begin
Result:=Pos('charset=',Data);
CharSet:=Copy(Data, Result,(PosEx('>',Data,Result)-Result));
if Result > 0 then
for Result := Length(CodePages)-1 downto 1 do
if Pos(CodePages[Result],CharSet) > 0 then
Break;
Result := ResArray[Result];
end; |
| Этот пользователь сказал Спасибо BBBCat за это полезное сообщение: | ||
Pcrepair (12.03.2013)
| ||