Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.09.30;
Скачать: CL | DM;

Вниз

Проверить ASCII строку   Найти похожие ветки 

 
writebuf(nil);   (2007-08-31 17:10) [0]

Как проверить ansi-строку на предмет того что она состоит только из символов ASCII, а не является юникодовой, UTF8?

Единственная моя идея - это в цикле проверять:

for i := 0 to Len(str) do
if Ord(str[i]) > $7F then notascii

Но это мне кажется моя ересь. Что-то есть нормальное?


 
Reindeer Moss Eater ©   (2007-08-31 17:18) [1]

Проверить то, что строка состоит только из какого-то множества символов - это значит убедиться, что в ней нет ни одного другого символа.

поэтому это не ересь:
Единственная моя идея - это в цикле проверять:


 
Anatoly Podgoretsky ©   (2007-08-31 18:43) [2]

> writebuf(nil);  (31.08.2007 17:10:00)  [0]

ASCII какой, us или extended?


 
writebuf(nil);   (2007-08-31 18:47) [3]


> ASCII какой, us или extended?


US


 
Anatoly Podgoretsky ©   (2007-08-31 19:05) [4]

> writebuf(nil);  (31.08.2007 18:47:03)  [3]

Тогда в него входят символы с кодами 32-127, плюс некоторое неодназначное подмножество из 0-31
Если подмножество не волнует, тогда можешь считать, что если встретился символ с кодом более $7F это уже не ASCII


 
Slym ©   (2007-09-03 14:23) [5]

для быстроты (оптимизация) можно по 4 байта проверять
var p:PInteger;
begin
p:=pointer(PChar(str));
for i := 0 to Len(str) div 4 do
begin
 if (p^ and $80)<>0 then notascii
 inc(p)
end;


 
Slym ©   (2007-09-03 14:24) [6]

if (p^ and $80808080)<>0 then notascii


 
Sha ©   (2007-09-03 17:15) [7]

> Slym ©

А как быть со строкой "я" ?


 
umbra ©   (2007-09-03 17:30) [8]


> Как проверить ansi-строку на предмет того что она состоит
> только из символов ASCII, а не является юникодовой, UTF8?
>

по-моему, вопрос поставлен неверно. Содержимое некоего буфера (строки) нельзя интрепретировать, не зная, что туда попало. UTF-8 и Unicode Определеяются по BOM, но опять таки, ВОМ стоит в начале файла, а не буфера. В общем, задача в такой постановке, по-моему, неразрешима.


 
Anatoly Podgoretsky ©   (2007-09-03 17:42) [9]

Ну то что неверно, это мягко сказано
ANSI никак не может быть ни юникодом, ни UTF8, иначе это не ANSI или ASCII


 
Anatoly Podgoretsky ©   (2007-09-03 17:44) [10]


> А как быть со строкой "я" ?

Что смущает, код равен FF или для OEM другой, но все равно выше 7F
Автор сделал уточнение

АП> ASCII какой, us или extended?
>
>
> US


 
Sha ©   (2007-09-03 17:52) [11]

> Anatoly Podgoretsky ©
> Что смущает...

смущает то,
что в [5]-[6] цикл проверки не выполнится ни разу,
и результат функции останется неопределенным.


 
Anatoly Podgoretsky ©   (2007-09-03 18:00) [12]

Ну это не единственная проблема, но я понимаю, что это как направление.
Теперь я понял, что ты имел ввиду, ну написал бы "z"
А то глаз зацепился за рускую букву


 
Sha ©   (2007-09-03 18:04) [13]

> Anatoly Podgoretsky ©
> Теперь я понял, что ты имел ввиду, ну написал бы "z"
> А то глаз зацепился за рускую букву

Русская, потому что мне автор телепатировал,
что по умолчанию он собирался сделать результат ASCII )


 
Sha ©   (2007-09-03 19:00) [14]

> Anatoly Podgoretsky ©   (03.09.07 18:00) [12]
> ... я понимаю, что это как направление.

тогда как-то так :)

function IsAsciiString(const s: string): boolean;
var
 p, q: pchar;
label
 NotASCII;
begin;
 p:=pointer(s);
 if p<>nil then begin;
   q:=@p[-SizeOf(integer)];                           //Pointer to string length
   q:=q+((pInteger(q)^+ (SizeOf(integer)-1)) and -2); //Pointer to the last word
   if (pWord(q)^ and $8080)<>0 then goto NotASCII;    //Test the last waord
   if p<>q then repeat;
     if (pInteger(p)^ and $80808080)<>0 then goto NotASCII; //Test current dword
     p:=p+SizeOf(integer);                            //Pointer to the next dword
     until p>=q;
   end;
 Result:=true;
 exit;
NotASCII:
 Result:=false;
 end;

procedure TForm1.Button2Click(Sender: TObject);
const
 Captions: array[boolean] of string= ("false", "true");
begin;
 Label1.Caption:=Captions[IsAsciiString(Edit1.Text)];
 end;


 
Anatoly Podgoretsky ©   (2007-09-03 19:31) [15]

> Sha  (03.09.2007 18:04:13)  [13]

А мне телепатировал, что US


 
Sha ©   (2007-09-03 20:44) [16]

Кстати, тут почти даром дается развертывание цикла,
в итоге обрабатываем по 8 символов за один проход цикла


function IsAsciiString(const s: string): boolean;
var
 p: pIntegerArray;
 q: pWordArray;
label
 NotASCII;
begin;
 p:=pointer(s);
 if p<>nil then begin;
   q:=@pchar(p)[-SizeOf(integer)];                        //Pointer to string length
   inc(pchar(q),(pInteger(q)^-1) and -2);                 //Pointer to the last word - 4
   if (q[2] and $8080)<>0 then goto NotASCII;             //Test the last word
   if (pinteger(q)^ and $80808080)<>0 then goto NotASCII; //Test the previous dword
   while pchar(p)<pchar(q) do begin;
     if (p[0] and $80808080)<>0 then goto NotASCII;       //Test the first dword
     if (p[1] and $80808080)<>0 then goto NotASCII;       //Test the second dword
     inc(pchar(p),2*SizeOf(integer));                     //Pointer to the next pair of dwords
     end;  
   end;
 Result:=true;
 exit;
NotASCII:
 Result:=false;
 end;


 
Sha ©   (2007-09-03 21:01) [17]

Ну и, наконец, размер цикла можно уменьшить до 18 байт,
если перед ним маску поместить в переменную:
m:=$80808080;



Страницы: 1 вся ветка

Текущий архив: 2007.09.30;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.025 c
3-1179810817
DeadMeat
2007-05-22 09:13
2007.09.30
Invalid Typecast


2-1188907422
ArtikZ
2007-09-04 16:03
2007.09.30
PrintScreen


15-1188541103
Шмелъ
2007-08-31 10:18
2007.09.30
Mail Observer Application


3-1180077871
MrNew
2007-05-25 11:24
2007.09.30
Не редактируеться ЗАПИСЬ?


2-1189071272
малой
2007-09-06 13:34
2007.09.30
FloatToInteger