Delphi FMX Проверить, содержит ли EditText только цифры? - PullRequest
0 голосов
/ 17 мая 2019

Мне нужно использовать разные процедуры в зависимости от Edittext.text

мне нужно вызвать ProcessA(value: string); с параметрами последних 4 символов строки, если первые 4 символа Edittext.text являются строками, а следующие 4являются числом.

и вызовом ProcessB(value:integer) с последними четырьмя номерами в качестве параметра, если все 8 символов являются числами?

Например: если EditText.Text равно ASDF1234, тогда я позвоню ProcessA и если EdiText.Text равно 12345678, тогда мне нужно позвонить ProcessB.

Показать ошибку, если строка похожа на ASD12345 или ASDFG123 или 1234567A или если числа указаны в десятичном виде.

Как я могу это проверить?

1 Ответ

3 голосов
/ 17 мая 2019
var
  Text: string;

  function CharInRange(C, FirstC, LastC: char): boolean; inline;
  begin
    Result := (C >= FirstC) and (C <= LastC);
  end;

  function IsDigitsOnly(const S: string;
    FirstIdx, LastIdx: integer): boolean;
  var
    I: integer;
  begin
    for I := FirstIdx to LastIdx do
    begin
      if not CharInRange(S[I], '0', '9') then
      begin
        Result := False;
        Exit;
      end;
    end;
    Result := True;
  end;

  function IsUpcaseLettersOnly(const S: string;
    FirstIdx, LastIdx: integer): boolean;
  var
    I: integer;
    C: char;
  begin
    for I := FirstIdx to LastIdx do
    begin
      C := S[I];
      if not CharInRange(C, 'A', 'Z') then
      begin
        Result := False;
        Exit;
      end;
    end;
    Result := True;
  end;

  procedure BadInput;
  begin
    raise Exception.Create('Bad Input');
  end;

begin
  Text := EditText.Text;
  if Length(Text) <> 8 then
  begin
    BadInput;
  end
  else if IsUpcaseLettersOnly(Text, 1, 4)
          and IsDigitsOnly(Text, 5, 8) then
  begin
    ProcessA(Copy(Text, 5, 4));
  end
  else if IsDigitsOnly(Text, 1, 8) then
  begin
    ProcessB(StrToInt(Copy(Text, 5, 4)));
  end
  else
  begin
    BadInput;
  end;
end;

В качестве альтернативы

uses
  ..., System.RegularExpressions;

var
  Text: string;
begin
  Text := EditText.Text;
  // I know this can be done better using a
  // single regex expression with capture groups, 
  // but I don't know the correct code to do that...
  if TRegEx.IsMatch(Text, '^[A-Z]{4}[0-9]{4}$') then
  begin
    ProcessA(Copy(Text, 5, 4));
  end
  else if TRegEx.IsMatch(Text, '^[0-9]{8}$') then
  begin
    ProcessB(StrToInt(Copy(Text, 5, 4)));
  end
  else
  begin
    raise Exception.Create('Bad Input');
  end;
end;
...