This is very old and outdated translation. If you can read English or Russian please use up-to-date English version or Russian version.

If you want to help to update the translation please contact me. New translation is based on GetText and can be edited with transifex.com. It is already machine-translated and need only proof-reading and may be some copy-pasting from here.


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](regular_expressions.html#engine).