Главная » Статьи » Программирование » Delphi&Pascal

Простая функция like (wildcard) сравнения строк

Простая функция like (wildcard) сравнения строк

Код сравнения строк с учетом wildcard символов может быть очень простым при рекурсивной реализации без предварительного разбора маски в какие-либо промежуточные структуры. Ниже приведен код функции, реализующей подобное сравнение (используются Ansi-строки - для unicode придется немного переделать).

  • Этот код достаточно эффективен при анализе небольших строк. Очень хорошо подходит, например, для сравнения путей файловой системы и тп. В частности, скорость работы существенно лучше реализации стандартного модуля Masks.

  • Функции предусматривают сравнение символов как с учетом регистра, так и без.

  • Предусмотрен файловый набор wildcard ?* и аналогичный sql набор _%. Причем могут использоваться одновременно оба и по аналогии с sql like можно задать Esc-символ. Все флаги сравнения и Esc-символ пакуются в дополнительный параметр вызова Op: Word.

Недостаток - глубокая рекурсия при сравнении (не подходит для длиных строк). Так же в отличие от реализации модуля masks отсутствуют множества в масках.

 

const
  // Опция сравнения по маске без учета регистра для Like
  likeText = 256;
  likeNoFile = 2048;
  likeNoSQL = 4096;


function LikePtr(S, Mask: PChar; Op: Word): boolean;

  function MskType: Integer;
  begin
    Result := 0;
    case Mask^ of
      '*'if likeNoFile and Op = 0 then Result := 2;
      '?'if likeNoFile and Op = 0 then Result := 1;
      '%'if likeNoSQL and Op = 0 then Result := 2;
      '_'if likeNoSQL and Op = 0 then Result := 1;
    else
      if Mask^ = Char(Lo(Op)) then Result := 3;
    end;
  end;

begin
  if Mask[0] = #0 then
    Result := S[0] = Mask[0]
  else begin
    case MskType of
      0begin
          Result := (S[0] = Mask[0]) or ((Op and likeText <> 0and (AnsiStrLIComp(S, Mask, 1) = 0));
          if Result and (S^ <> #0then
            Result := LikePtr(@S[1], @Mask[1], Op);
        end;
      1if S^ <> #0 then
          Result := LikePtr(@S[1], @Mask[1], Op)
        else
          Result := False;
      2: Result := LikePtr(S, @Mask[1], Op) or ((S^ <> #0and LikePtr(@S[1], Mask, Op));
      3: Result := (S[0] = Mask[1]) and ((S^ <> #0and LikePtr(@S[1], @Mask[2], Op));
    else
      Result := False;
    end;
  end;
end;

function Like(const S, Mask: String; Op: Word): boolean;
begin
  Result := LikePtr(PChar(S), PChar(Mask), Op);
end;
 

Категория: Delphi&Pascal | Добавил: alexeevd (26.05.2010)
Просмотров: 1527 | Рейтинг: 5.0/1
Всего комментариев: 0
Имя *:
Email *:
Код *: