| 
| 
 | Вопрос # 5 872/ вопрос решён / | 
 |  Здравствуйте, эксперты!Как можно проверить соответствие текстовой строки маске ввода EditMask?
 
|  |   Вопрос задала: Галка (статус: Посетитель)Вопрос отправлен: 11 января 2012, 23:31
 Состояние вопроса: решён, ответов: 1.
 |  Ответ #1. Отвечает эксперт: meson Здравствуйте, Галка!
 Уточните, пожалуйста, что Вы хотите проверить.
 Лучше бы с примерами.
 
 Вообще-то свойство EditMask регламентирует ввод символов.
 Можно, например, задать такую маску, которая заставит компонент
 игнорировать все кроме цифр и символов + или -.
 Посмотрите также примеры в сети.
 Вот один из них на вскидку
 http://subscribe.ru/archive/comp.soft.prog.mydelphi7/200403/19061248.html
 
 Я правильно понял Ваш вопрос?
 
|  | Ответ отправил: meson (статус: 1-ый класс)Время отправки: 12 января 2012, 02:37
 
 |  
 Мини-форум вопросаВсего сообщений: 16; последнее сообщение — 17 января 2012, 16:34; участников в обсуждении: 5. 
|   | min@y™ (статус: Доктор наук), 12 января 2012, 08:16 [#1]:Речь идёт о компоненте TMaskEdit? Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | Галка (статус: Посетитель), 12 января 2012, 10:30 [#2]:В общем, речь идет именно о нем (о TMaskEdit  ), сложность в том, что маску накладывать можно не во всех случаях, а проверять введенную строку на соответствие ей все таки нужно. Единственный вариант, который мне приходит в голову - посимвольный анализ строки, но он мне кажется излишне тяжеловесным. |  
|   | min@y™ (статус: Доктор наук), 12 января 2012, 11:22 [#3]: Цитата (Галка): Единственный вариант, который мне приходит в голову - посимвольный анализ строки, но он мне кажется излишне тяжеловесным.  Ну и замени нафиг ты свой MaskEdit на обычный Edit и проверяй введённую строку на соответствие маске с помощью функции MatchesMask() из модуля Masks.pas или с помощью вот этой самодельной:
 
 // Соответствие строки заданной маске
function MatchesMask(const S, Mask: string): Boolean;
var
  si, mi: Integer;
  b: Boolean;
begin
  if Mask = ''
    then begin
           Result:= True;
           Exit;
         end;
 
    si:= 1;
    mi:= 1;
 
    while mi <= Length(mask) do
      begin
        case mask[mi] of
          '?': begin
                 Inc(si);
                 Inc(mi);
                 Continue;
               end; // '?':
 
          '*': begin
                 if mi = Length(mask)
                   then begin
                          Result:= True;
                          Exit
                        end;
 
                 Inc(mi);
 
                 while si <= Length(s) + 1 do
                   begin
                     b := MatchesMask(Copy(s, si, Length(s) - si + 1),
                                      Copy(mask, mi, Length(mask) - mi + 1));
                     if b
                       then begin
                              Result:= True;
                              Exit
                            end;
 
                     Inc(si);
                   end; // while
 
                 Result:= False;
                 Exit;
               end; // '*':
          else begin
                 if si > Length(s)
                   then begin
                          Result:= False;
                          Exit
                        end;
 
                 if s[si] <> mask[mi]
                   then begin
                          Result:= False;
                          Exit;
                        end;
               end // else
        end; // case
 
        Inc(si);
        Inc(mi);
    end; // while
 
  Result:= (si = Length(s) + 1) and (mi = Length(mask) + 1);
end;Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | Галка (статус: Посетитель), 12 января 2012, 11:53 [#4]:MatchesMask() - функция, проверяющая имя файла на соответствие маске, функция, приведенная в примере - тоже. Может, я не корректно задала вопрос, попробую с примером:
 Строка маски: '00 LL 999999;1;_;'.
 Строка 23 ВА 789564 соответствует этой маске, 23 ВА 45НН78 - не соответствует.
 Можно ли это как-то проверить, не перебирая строку посимвольно?
 |  
|   | min@y™ (статус: Доктор наук), 12 января 2012, 13:31 [#5]: Цитата (Галка): Можно ли это как-то проверить, не перебирая строку посимвольно?  В любом случае проверка - это именно посимвольный перебор. У тебя условие-то какое?
 ЦифраЦифра БукваБуква ЦифраЦифраЦифраЦифраЦифраЦифра? Так, что ли?
 Делаю лабы и курсачи по Delphi и Turbo Pascal. За ПИВО! Пишите в личку, а лучше в аську. А ещё лучше - звоните в скайп! |  
|   | Галка (статус: Посетитель), 12 января 2012, 14:23 [#6]:У меня условие динамическое, оно в базе хранится и из нее достается. Есть функция FormatMaskText, которая теоретически должна возвращать текст с примененной к нему маской, пыталась с ней сравнивать, но она буквы от цифр не отличает. То есть, применяя маску к '00 LL 999999;1;_;' к строке 23 ВА 45НН78 она в этой строке ничего не меняет, буквы НН остаются, хотя на этих позициях, вроде как, цифры должны быть
 |  
|   | Вадим К (статус: Академик), 12 января 2012, 17:29 [#7]:а может просто начать использовать регулярные выражения? Они более гибкие и более документированы. Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Галка (статус: Посетитель), 12 января 2012, 17:41 [#8]:А как можно связать регулярные выражения с использованием маски ввода? Мне кажется, они здесь неприменимы |  
|   | Вадим К (статус: Академик), 12 января 2012, 19:24 [#9]:а я не говорил, что нужно связывать. Нужно просто отказаться от маски ввода. Раз условие динамически генерируется, ничего не мешает генерировать регулярку. Галочка "подтверждения прочтения" - вселенское зло. |  
|   | Галка (статус: Посетитель), 12 января 2012, 19:45 [#10]:Пока не уложилось, но попробую. Спасибо за идею  ) |  
|   | meson (статус: 1-ый класс), 12 января 2012, 23:13 [#11]:Вадим К: В отношении полезности регулярных выражений полностью с Вами согласен! 
 Галка: Простите за тупость, похоже я один участников не понимаю проблемы..
 
 Вы пишете
 
 маску накладывать можно не во всех случаяхА собственно, почему? Разве не любую строку можно можно присвоить строковому свойству?
 И менять ее в RunTime можно сколько угодно.
 Другое дело - соответствует ли эта строка разумному формату.
 
 Возможно трудность состоит в построении маски,
 которая удовлетворяла бы тому, что Вы предполагаете вводить в MaskEdit.
 Но тогда напрашивается другой вопрос.
 Что Вы собираетесь делать с результатом ввода?
 Если подвергать дальнейшему анализу, то стоит ли
 - использовать "точную" маску?
 - использовать маску вообще?
 
 Например вот такой маске
 "00 LL aaaaaa;1;_"
 соответствует как строка "23 ВА 789564", так и строка "23 ВА 45НН78".
 |  
|   | Галка (статус: Посетитель), 13 января 2012, 16:09 [#12]:meson: Маска в поле меняется, накладывается и снимается динамически в зависимости от значений других полей. Хочется при наложении маски проверять, соответствует ли ей то, что уже введено в поле. Если накладывать маску сверху, без валидации значения поля, пользователь может увидеть нечто существенно отличающееся от фактического значения поля и отличающееся от формата описанного маской. |  
|   | Вадим К (статус: Академик), 13 января 2012, 16:44 [#13]:мое мнение - MaskEdit лучше не использовать, а просто рядом с полем ввода отображать зеленую галочку/желтый треугольник. Галочка "подтверждения прочтения" - вселенское зло. |  
|   | meson (статус: 1-ый класс), 13 января 2012, 20:56 [#14]:Галка: Спасибо, теперь и я понял что Вам нужно сделать!
  
 В принципе я согласен с мнением Вадима.
 Но если не хочется отказываться от MaskEdit, можно поступить так.
 
 Перед сменой маски запоминаем содержимое MaskEdit с освобождаем его.
 После наложения новой маски записываем в MaskEdit сначала первый символ из запомненной строки, затем два первых и так далее.
 Каждый раз проверяем удалась ли попытка.
 После первой неудачной попытки выходим из цикла.
 
 В результате:
 - в MaskEdit остается только допустимая часть строки
 - есть возможность известить пользователя о неудаче
 - удалось избежать анализа строки
 |  
|   | bugmenot (статус: 3-ий класс), 13 января 2012, 23:40 [#15]:интересующий вас код уже написан и находится в методе TCustomMaskEdit.ValidateEdit виконання програми розпочинається з того самого мiсця, де призупинилося.
 
 |  
|   | Галка (статус: Посетитель), 17 января 2012, 16:34 [#16]:Все же написала функцию посимвольной проверки. Всем спасибо за советы
   |  17 января 2012, 16:34: Статус вопроса изменён на решённый (изменил автор вопроса — Галка) Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |