Фирма Borland не включила в свою библиотеку этот часто очень необходимый инструмент. Эту ситуацию попытался исправить Андрей Сорокин, написав замечательный компонент TRegExpr (статья на Королевстве "Текст с высоты птичьего полета или Регулярные выражения"). Однако возможность использовать регулярные выражения в Delphi существует и без этого компонента. Эта возможность предоставлена фирмой Microsoft в библиотеке VBScript (vbscript.dll версии 5.0 и выше), поставляемой в составе Windows, начиная с версии 98. Скачать обновления VBScript можно здесь или здесь.
Для подключения RegExp необходимо импортировать библиотеку типов Microsoft VBScript Regular Expressions и создать модуль библиотеки типов (смотрите рисунок).
В библиотеку будут включены объекты (интерфейсы) RegExp, MatchCollection, Match, SubMatches и класс-наследник TOLEServer TRegExp.
Для использования в uses включим сгенерированный модуль VBScript_RegExp_55_TLB.pas.
Объект VBScript RegExp (IRegExp2) имеет 4 свойства и 3 метода.
Свойства объекта RegExp:
Свойство |
Назначение |
Pattern |
Строка, содержащая регулярное выражение. Должна быть задана до использования методов RegExp |
IgnoreCase |
Тип Boolean. Если True, то игнорирует регистр символов, по-умолчанию False. Соответствует модификатору "i". |
Global |
Тип Boolean. Если True, то RegExp будет пытаться найти все возможные соответствия в строке. Соответствует модификатору "g". |
Multiline |
Тип Boolean. Если True, то RegExp будет поддерживать многострочный режим, по-умолчанию False. Соответствует модификатору "m". |
|
Другие модификаторы (x, s, r и др.) в выражениях VBScript RegExp не поддерживаются.
Методы объекта RegExp:
Метод |
Назначение |
Test(search-string) |
Тестирует строку search-string на соответствие паттерну. В случае удачи возвращает True. |
Replace(search-string, replace-string) |
Метод имеет два аргумента: строку, в которой будет осуществляться поиск и строку замены. Все найденные соответствия в строке search-string, заданные в Pattern, будут замещены значениями, указанными в строке замены replace-string. |
Excecute(search-string) |
Работает как Test, только все найденные соответвия в строке search-string, заданные в Pattern, будут возвращены в коллекции MatchCollection (см. ниже), содержащей объекты Match. |
|
Содержит коллекцию объектов соответствия Match. Имеет два свойства: Count возвращает количество найденных соответствий, Item содержит объект Match с индексом от 0 до Count - 1. В VBScript RegExp версии 5.5 Item является свойством default, т.е. к свойству Item обращаться не обязательно, т.е. при обращении к объекту типа Matches Item можно опускать.
Объект Match (IMatch2) содержит найденное в строке соответствие, заданное в паттерне поиска. Имеет 4 свойства:
Метод |
Назначение |
FirstIndex |
Позиция найденного соответствия в строке |
Length |
Длина найденной строки |
Value |
Текст найденного соответствия |
SubMatches |
Колекция субсоответствий. Субсоответствия задаются группировкой с помощью круглых скобок "(" и ")" (см. http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/html/jsgrpregexpsyntax.asp). |
|
Содержит коллекцию субсоответствий. Это как бы соответствия в соответствии. Имеет два свойства: Count - количество найденных субсоответствий и Item (default - можно опустить) возвращает текст найденного субсоответствия с индексом от 0 до Count - 1.
Например, задан RegExp паттерн '(\d*)\.?(\d*)', строка поиска '123.45', тогда коллекция SubMatches вернет нам Count = 2, Item[0] = '123' и Item[1] = '45'.
Разбор строки URL на составляющие пример взят с сайта MSDN
procedure TForm1.Button1Click(Sender: TObject);
var
R: TRegExp;
mc: MatchCollection;
m: Match;
sm: SubMatches;
i, j: Integer;
begin
R := TRegExp.Create(Self);
try
R.Pattern := '(\w+):\/\/([^/:]+)(:\d*)?([^#]*)(.*)';
R.IgnoreCase := True;
R.Global := False;
Memo1.Lines.Clear;
mc := R.Execute(' http://msdn.microsoft.com:80/sctipting/default.htm#123')
as MatchCollection;
if mc.Count > 0 then begin
for i := 0 to mc.Count - 1 do begin
m := mc[i] as Match;
Memo1.Lines.Add(Format(' Match[%d] = "%s"', [i, m.Value]));
sm := m.SubMatches as SubMatches;
for j := 0 to sm.Count - 1 do
Memo1.Lines.Add(Format(' SubMatch[%d] = "%s"', [j,
VarToStr(sm.Item[j])]));
end;
end;
finally
m := nil;
sm := nil;
mc := nil;
R.Free;
end;
end;
|
|
Теперь рассмотрим подробнее. В строке R.Pattern := '(\w+):\/\/([^/:]+)(:\d*)?([^#]*)(.*)' записываем паттерн регулярного выражения. Далее в mc := R.Execute(' http://msdn.microsoft.com:80/sctipting/default.htm#123') as MatchCollection; получаем коллекцию найденных соответсвий (MatchCollection). Получаем объект Match в переменную m := mc[i] as Match; и субсоответствия в переменную sm := m.SubMatches as SubMatches;
Результатом работы данного примера в Memo1 будет записано следующее:
Match[0] = "http:
SubMatch[0] = "http"
SubMatch[1] = "msdn.microsoft.com"
SubMatch[2] = ":80"
SubMatch[3] = "/sctipting/default.htm"
SubMatch[4] = "#123"
|
|
Где первая строка - это найденное соответствие Match, а остальные - субсоответствия (SubMatches).
пример взят с сайта MSDN
procedure TForm1.Button2Click(Sender: TObject);
var
mc: MatchCollection;
S: String;
begin
with TRegExp.Create(Self) do
try
Pattern := Format('[-+]?([0-9]*\%s)?[0-9]+([eE][-+]?[0-9]+)?',
[DecimalSeparator]);
IgnoreCase := True;
Global := True;
S := '';
mc := Execute('5.23') as MatchCollection;
if mc.Count = 1
then ShowMessageFmt('Число "%s" задано верно', [(mc [0] as Match).Value])
else ShowMessage('Это не число!');
finally
mc := nil;
Free;
end;
end;
|
|
пример взят с сайта MSDN
procedure TForm1.Button5Click(Sender: TObject);
var
R: TRegExp;
begin
R := TRegExp.Create(Self);
try
R.Pattern := '([a-zа-я]+) \1';
R.IgnoreCase := True;
R.Global := True;
R.Multiline := True;
ShowMessage(R.Replace('Стоимость стоимость газолина все все растет растет?'#10 +
'Is is the cost of of gasoline going up up?', '$1'));
finally
R.Free;
end;
end;
|
|
Скачать пример к статье MSRegExp.zip (9.5 K)
Взято тут: http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1062
Источник: http://www.delphikingdom.com/asp/viewitem.asp?catalogid=1062 |