Шаблон поиска в строке с использованием подстановочного знака в Delphi?

#delphi #pattern-matching #delphi-xe

#delphi #сопоставление с шаблоном #delphi-xe

Вопрос:

Раньше я использовал библиотеку HYPERSTR для процедуры обработки строк. Теперь я использую более новый Delphi. Мне нужно выполнить поиск шаблона в строке, например, старой функции function IsMatchEx(const Source, Search:AnsiString; var Start:integer) : Integer; . На самом деле мне не нужно значение результата, я просто хочу знать, совпадает ли шаблон со строкой или нет.

Мой старый код (возвращает TRUE):

 var
  StartPos: integer;
  FoundPos: integer;
begin
  StartPos := 1;
  FoundPos := IsMatchEx('abcdef', 'abcd?f', StartPos);
  if FoundPos > 0 then
    showmessage('match');
end;
  

Я вижу, что в Delphi XE есть TRegEx, но я все еще не понимаю, как его использовать.

Этот код не возвращает TRUE :

   if TRegEx.IsMatch('abcdef', 'abcd?f') then
    showmessage('match');
  

Я также получил тот же результат при использовании MatchesMask .

Спасибо.

Комментарии:

1. Думаю, вы используете ‘.’ для сопоставления с одним символом.

2. Действительно? MatchesMask должен был сработать. Вы уверены, что ваш тест был корректным?

3. @Rob, я имею в виду, что MatchesMask не работает в моем реальном случае. С помощью точки моя проблема решена. Извините за поздний ответ, потому что мне нужно исправить некоторые коды, чтобы я мог попробовать ответ от MGH.

Ответ №1:

Синтаксис регулярного выражения отличается. ? и * имеют разные значения. Смотрите http://www.regular-expressions.info/tutorial.html за отличное введение в регулярные выражения. Вы бы использовали что-то похожее на abcd [a-z] f или abcd wf, или даже другой синтаксис, в зависимости от того, чему вы хотели бы соответствовать.

Комментарии:

1. 1 за ссылку, которую вы предоставили самостоятельно. Я бы также посоветовал, чтобы, если вы собираетесь потратить какое-то время на регулярные выражения, вы вложили средства в копию RegexBuddy . Это бесценный инструмент для создания и тестирования регулярных выражений. (Никоим образом не связан — просто очень довольный клиент уже много лет.)

Ответ №2:

если ? представляют собой один символ:

   if TRegEx.IsMatch('abcdef', 'abcd.f') then
    showmessage('match');
  

если ? представляет собой любое жало:

   if TRegEx.IsMatch('abcdef', 'abcd.*f') then
    showmessage('match');
  

У вас нет XE, поэтому вы не тестировали.

Комментарии:

1. Остерегайтесь точки … 😉 regular-expressions.info/dot.html , например, он будет соответствовать abcdef, но он также будет соответствовать abcd,f abcd / f, abcd (f и т.д. Регулярное выражение может использовать более мощный синтаксис, чтобы получить именно то, что вам нужно для соответствия.

2. @user ‘.’ не соответствует, если у вас есть символы новой строки, я думаю, тогда вам нужно использовать ‘[.n r]’ вместо ‘.’

3. Хм .. Я думаю, что новой строки не будет. Входными данными является шестнадцатеричная строка из файла. Почему-то я думаю, что мой strtohex имеет недопустимый результат, поэтому я должен сначала это исправить, и пришло время возвращаться домой! 🙂

4. При шестнадцатеричном вводе вы, скорее всего, захотите использовать предложение ldsandon, чтобы соответствовать тому, что вы на самом деле хотите. [0-9a-fA-F] * должен соответствовать шестнадцатеричному.

5. Не должна ли маска первого примера быть ‘abcd.?’, а не ‘abcd.f’ ?

Ответ №3:

Вы можете использовать TMask для сопоставления подстановочных знаков:

 TMask *m = new TMask("String to check");
bool isMatch = m->Matches("string to*");
delete m;
  

IsMatch = true
(Код C Builder можно просто перевести на Pascal)