// Um möglichst schnell zu prüfen, ob ein String (nur) eine Zahl
// enthält, habe ich
(trotz Null-Ahnung von Assembler) den folgenden
// Code gebastelt, der außerdem die richtige Stelle von Tausender-Punkten
// sowie von Vorzeichen in Dezimalzahlen überprüftt. Hexadezimal-Zahlen
// dürfen "$" oder "#" voranstehen, sie dürfen aber keinen Punkt, kein
// "+" und kein "-" enthalten. Zum besseren Verständnis hier eine kleine
// Tabelle:

String Zahl?
123456789 True
1.23456789 False
.123456789 False
123.456.789 True
1234,56789 True
1234.567.890 False
123,456.789 False
12345,67e-4 True
#123456789 True
$123FFFFFF True
#12345ABe+2 False
$123CfDaEE True
-$12345ABC False
$3.FFF.FFF False
,123456789 False
123456789, False
123.456.789. False

// Getestet mit D2010 unter W7
// überarbeitet 4.12.2016

var 
  Komma, Punkt: byte; 
 
procedure TForm1.FormCreate(Sender: TObject); 
begin 
  Komma := ord(Decimalseparator); 
  Punkt := ord(ThousandSeparator); 
end; 
function isZahl(p: PWideChar): boolean; stdcall; 
asm 
  push ebx 
  push esi 
  push edi 
  xor ecx, ecx 
  xor esi, esi 
  mov edi, esi 
  mov edx, p 
  mov ebx, edx 
  mov al, [edx] 
  cmp al, Komma 
  je @false 
  cmp al, '$' 
  je @ishex 
  cmp al, '#' 
  jne @schleife 
 @ishex: 
  mov ecx, $F00000 
  add edx, 2  // inc edx    falls kein WideChar 
 @schleife: 
  mov al, [edx] 
  cmp al, 0 
  jne @plus 
  cmp edx, ebx 
  je @false 
  mov al, [edx-2]   // [edx-1] 
  cmp al, Komma 
  je @false 
  jmp @true 
 @plus: 
  cmp al, '+' 
  jne @minus 
 @vorzeichen: 
  cmp ecx, $F00000 
  jge @false 
  cmp ch, 0 
  jne @false 
  mov ch, 1 
  cmp edx, ebx 
  je @eins 
  mov ah, [edx-2]  // [edx-1] 
  cmp ah, 'e' 
  je @weiter 
  cmp ah, 'E' 
  je @weiter 
 @eins: 
  mov ah, [edx+2]  // [edx+1] 
  cmp ah, 0 
  je @false 
  cmp edx, ebx 
  jne @false 
  cmp ah, 'e' 
  je @false 
  cmp ah, 'E' 
  je @false 
  jmp @weiter 
 @minus: 
  cmp al, '-' 
  jne @komm 
  jmp @vorzeichen 
 @komm: 
  cmp al, Komma 
  jne @e 
  sub esi, edi 
  cmp esi, 4 
  jne @ohne 
  jmp @mit 
 @ohne: 
  cmp edi, 0 
  jne @false 
 @mit: 
  xor edi, edi 
  cmp cl, 0 
  jg @false 
  cmp ecx, $101 
  jg @false 
  mov cl, 1 
  jmp @weiter 
 @e: 
  cmp al, 'e' 
  je @etest 
  cmp al, 'E' 
  jne @ziffer 
 @etest: 
  cmp ecx, $101 
  jg @hex 
  cmp edx, ebx 
  je @false 
  or ecx, $10000 
  xor ch, ch 
  jmp @weiter 
 @ziffer: 
  cmp al, Punkt 
  je @ish 
  cmp al, '0' 
  jl @hex 
  cmp al, '9' 
  jle @weiter 
 @hex: 
  cmp ecx, $F00000 
  jl @false 
  cmp al, 'A' 
  jl @false 
  cmp al, 'F' 
  jle @weiter 
  cmp al, 'a' 
  jl @false 
  cmp al, 'f' 
  jg @false 
 @weiter: 
  add edx, 2    // inc edx 
  inc esi 
  jmp @schleife 
 @ish: 
  cmp ecx, $F00000 
  jge @false 
  cmp cl, 0 
  jg @false 
  cmp esi, 0 
  je @false 
  cmp edi, 0 
  je @anf 
  sub esi, edi 
  cmp esi, 4 
  jne @false; 
  jmp @first 
 @anf: 
  cmp esi, 4 
  jge @false; 
 @first: 
  mov edi, esi 
  jmp @weiter 
 @false: 
  mov @result, 0 
  jmp @raus 
 @true: 
  cmp edi, 0 
  je @kp 
  sub esi, edi 
  cmp esi, 4 
  jne @false 
 @kp: 
  mov result, 1 
 @raus: 
  pop edi 
  pop esi 
  pop ebx 
end; 

 
// Beispiel 1 
 
  procedure TForm1.Button1Click(Sender: TObject); 
  var 
    s: string; 
    b: boolean; 
  begin 
    s := '8.143.526,2763e-2'; 
    b := isZahl(PWideChar(s)); 
    if b then 
      Label1.Caption := 'OK' 
    else 
      Label1.Caption := 'Keine zugelassene Zahl'; 
  end; 
 
// Beispiel 2 
 
  procedure TForm1.Button2Click(Sender: TObject); 
  var 
    s: string; 
  begin 
    s := '#1AfBc0'; 
    if isZahl(@s[1]) then 
      showmessage('Das ist eine Zahl') 
    else 
      showmessage('Keine exakte Zahl') 
  end;



Zugriffe seit 6.9.2001 auf Delphi-Ecke