FAQ (Често задавани въпроси)

Q
въпрос
A
отговор

Q. Как мога да използвам TRegExpr в Borland C++ Builder?

Имам проблем, понеже няма хедър-файлове (.h или .hpp).

A.

  • Добавете RegExpr.pas в проект bcb
  • Компилирайте проекта. Това ще генерира файла RegExpr.hpp
  • Вече може да се пише код, който използва unit-а RegExpr
  • Не забравяйте да добавите \#include "RegExpr.hpp" където е необходимо

Q. Защо TRegExpr връща повече от един ред?

Например RE <font .\*> връща първия <font, и след това останалата част от файла, вкл. последния </html>

A.

За съвместимост с по-стари версии модификаторът /s е включен по подразбиране.

Изключете го (например чрез ModifierS := false или за всички НОВИ обекти RegExprModifierS := false) и . ще съвпада с всичко освен \n – така, както искате.

BTW препоръчвам <font (\[^\\n>\]\*)>, тогава в Match\[1\] ще бъде URL.

Q. Защо TRegExpr връща повече, отколкото очаквам?

Например, шаблонът <p>(.+)</p> , приложен към стринг <p>a</p><p>b</p> връща a</p><p>b , а не a, както очаквам.

A.

По подразбиране всички оператори работят в жаден  режим, т.е. дават колкото е възможно по-голямо съвпадение.

Ако искате да работят в нежаден режим, можете или да използвате нежадни оператори като +? и др. (ново във версия v. 0.940), или да превключите всички оператори в нежаден режим с помощта на модофокатора g (използвайте съответните свойства на TRegExpr или конструкции от типа ?(-g) направо в RE).

Q. Как да правя parse на сорсове като HTML с помощта на TregExpr?

A. Съжалявам, това е почти невъзможно!

Разбира се, може да използвате TRegExpr за лесно извличане на информация от HTML, както съм показал в примера си, но ако искате истински parsing ще трябва да използвате истинсли parser, не RE!

Може да прочетете подробното обяснение в книгата на Tom Christiansen и Nathan Torkington Perl Cookbook например. Накратко – има много конструкции, на които може лесно да се прави parse от истински parser, но не и от RE, и истинският parser МНОГ ПО-БЪРЗО прави parsing-а, защото RE не сканират просто входния поток, той прави и оптимизиращи търсения, което отнема доста повече време.

Q. Има ли начин за получаване на многократни съвпадения на шаблон в TRegExpr?

A.

Може да направите цикъл и да правите постъпкови съвпадения с метода ExecNext.

Това не може да стане лесно, понеже Delphi не е интерпретатор, какъвто е Perl (и в това е предимството му – интерпретаторите работят много бавно!).

Ако имате нужда от пример, разгледайте реализаията на метода TRegExpr.Replace или погледнете примерите в HyperLinksDecorator.pas

Q. Аз проверявам потребителския вход. Защо TRegExpr връща True при грешно въведен текст от потребителя?

A.

В много от случаите потребителите на TRegExpr забравят, че RE е за ТЪРСЕНЕ във входния стринг. Така, че ако искате да накарате потребителя да въвежда само 4 цифри и за това използвате шаблона \\d{4,4}, може да пропуснете грешни въвеждания от типа 12345 или букви 1234 и други букви. Трябва да добавите  проверки за начало и край на реда, за да сте сигурни, че няма нищо наоколо: ^\\d{4,4}$.

Q. Защо нежадните итератори понякога изглежда, че работят в жаден режим?

Например, RE a+?,b+? , приложена към стринга aaa,bbb , връща aaa,b, а не би ли трябвало да връща a,b заради нежадния първи итератор?

A.

Това е ограничение на използваната в TRegExpr (и в  Perl и в много RE под Unix) математика – RE прави само проста оптимизация при търсене, и не се опитва да прави най-добрата оптимизация. В някои случаи това е лошо, но като цяло е по-скоро предимство, отколкото ограничение – заради производителността и предвидимостта на резултатите.

Основното правило е – RE най-напред се опитва да направи съвпадение от текущата позиция и само ако е напълно невъзможно, се премества напред с един символ и отново опитва от новата позиция. Така, че ако използвате a,b+? , се открива a,b, но в случай на a+?,b+? , не е задължително (заради нежадността), но е възможно да се даде съвпадение за повече от едно a, така, че TRegExpr го прави и накрая връща коректния (но не оптимален) резултат. TregExpr, както и RE на Perl или Unix не се опитват да се придвижват напред и да проверяват дали ще има по-добро съвпадение. Нещо повече, те  изобщо не могат да определят кое съвпадение е по-добро и кое – по-лошо.

Мпля, прочетете [Syntax](regexp_syntax.html#engine).