Skip to content

ЧЗВ

Открих ужасен бъг: TRegExpr предизвиква изключение за нарушение на достъпа!

Отговор

Трябва да създадете обекта преди употреба. Така че, след като декларирате нещо като:

r : TRegExpr

не забравяйте да създадете инстанция на обекта:

r := TRegExpr.Create.

Поддържа ли Unicode?

Отговор

Как да използвате Unicode

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

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

Отговор

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

Изключете го и . ще съответства на всеки символ, освен разделители на редове - точно както искате.

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

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

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

Отговор

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

Ако искате режим „неалчен“, можете да използвате оператори като +? и така нататък или да превключите всички оператори в режим „неалчен“ с помощта на модификатор g (използвайте подходящите свойства на TRegExpr или оператор ?(-g) в р.и.).

Как да анализирам източници като HTML с помощта на TRegExpr?

Отговор

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

Разбира се, лесно можете да използвате TRegExpr за извличане на някоя информация от HTML, както е показано в моите примери, но ако искате точен анализ, трябва да използвате истински парсер, а не р.и.

Можете да прочетете пълното обяснение, например, в Perl Cookbook на Том Кристиансен и Нейтън Торкингтън.

Накратко - има много структури, които могат лесно да бъдат анализирани от истински парсер, но изобщо не могат да бъдат от р.и., и истинският парсер много по-бързо извършва анализа, защото р.и. не просто сканира входния поток, той извършва оптимизационно търсене, което може да отнеме много време.

Има ли начин да получа множество съвпадения на модел в TRegExpr?

Отговор

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

Ако искате някакъв пример, моля, разгледайте имплементацията на метода TRegExpr.Replace или примерите за HyperLinksDecorator

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

Отговор

В много случаи потребителите на TRegExpr забравят, че регулярното изражение е за търсене във входния низ.

Така че, например, ако използвате израза \d{4,4}, ще получите успех за грешни потребителски входове като 12345 или всякакви букви 1234.

Трябва да проверите от началото до края на реда, за да сте сигурни, че около него няма нищо друго: ^\d{4,4}$.

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

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

Отговор

Това е поради начина на работа на TRegExpr. Фактически много други двигатели за р.и. работят точно по същия начин: те извършват само проста оптимизация на търсенето и не се опитват да направят най-добрата оптимизация.

В някои случаи това е лошо, но като цяло това е по-скоро предимство, отколкото ограничение, поради причини за производителност и предвидимост.

Основното правило - р.и. първо опитва да намери съвпадение от текущото място и само ако това е напълно невъзможно, се движи напред с един знак и опитва отново от следващата позиция в текста.

Така че, ако използвате a,b+?, то ще съответства на a,b. В случай на a+?,b+? вече не се препоръчва (добавихме модификатор за неалчност), но все още е възможно да съответства на повече от едно a, така че TRegExpr ще го направи.

TRegExpr като Perl или Unix r.e. не се опитва да се движи напред и да проверява - ще бъде ли "по-добро" съвпадение. Първо и най-важно, просто защото няма начин да се каже, че съвпадението е по-добро или по-лошо.

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

Имам проблем, тъй като не е наличен файл за заглавие (.h или .hpp).

Отговор

  • Добавете RegExpr.pas към проекта bcb.
  • Компилирайте проекта. Това генерира файлът за заглавие RegExpr.hpp.
  • Сега можете да пишете код, който използва единицата RegExpr.
  • Не забравяйте да добавите #include “RegExpr.hpp”, където е необходимо.
  • Не забравяйте да замените всички \ в регулярните изрази с \\ или да преопределите константата EscChar.

Защо много р.и. (включително р.и. от помощта и демото на TRegExpr) работят грешно в Borland C++ Builder?

Отговор

Подсказката е в предишния въпрос ;) Символът \ има специално значение в C++, така че трябва да го екранирате (както е описано в предишния отговор). Но ако не ви харесват р.и. като \\w+\\w+\\.\\w+, можете да преопределите константата EscCharRegExpr.pas). Например EscChar = "/". Тогава можете да пишете /w+/w+/./w+, изглежда необичайно, но е по-четимо.