ЧЗВ
Открих ужасен бъг: TRegExpr предизвиква изключение за нарушение на достъпа!
Отговор
Трябва да създадете обекта преди употреба. Така че, след като декларирате нещо като:
r : TRegExpr
не забравяйте да създадете инстанция на обекта:
r := TRegExpr.Create.
Поддържа ли 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+
, можете да преопределите константата EscChar
(в RegExpr.pas
). Например EscChar = "/"
. Тогава можете да пишете /w+/w+/./w+
, изглежда необичайно, но е по-четимо.