Archive for the ‘Regex’ Category

SgmlReader

Saturday, May 30th, 2009

Ha htmlt kell kódból parsolni, akkor jól jöhet ez a kis lib. Annak idején egy ms jóember írta meg, de sokáig senki nem frissítette, most kézbe vette egy cég az ügyet, és vannak rendszeresen bugfix kiadások.

Arról szól a dolog, hogy nem teljesen korrekt html tartalmat is kiegyenget, mint a htmltidy, és utána már xml domban fel lehet dolgozni a tartalmat. Sokkal jobb megoldás, mint regexszel bíbelődni.

.NET teljesítményhangolási tapasztalatok 2.

Tuesday, February 3rd, 2009

Regexek használata esetén lehetőség van a regex előfordítására, amely során a konkrét regex kifejezésre generálnak egy kiértékelő assemblyt, ami aztán gyorsabban képes a regexet lefuttatni egy adott bemeneti szövegen, mint a nem előfordított megfelelője. Az előfordítás költsége igen magas, amely csakis akkor éri meg, ha utána nagyon sokszor kell a regexet különböző szövegekre lefuttatni. Ha csak egyszer használjuk fel a regexet és csak rövid bemenetekre, akkor sokkal de sokkal többet veszítünk az előfordítással, mint nyerünk.

Az egyik third-party vezérlőben volt az alábbi kód:

Regex regex = new Regex(@”\w+|[^A-Za-z0-9_]”, RegexOptions.Compiled |
RegexOptions.IgnoreCase);

A RegexOptions.Compiled ebben a felhasználásban (egysoros textbox) nagyon sok időt elvitt, indokolatlanul.

Az előfordítás további problémás jellemzője, hogy sokféle regex esetén minden egyes regexhez létrejön és betöltődik egy dinamikus assembly a memóriába, amely csak az appdoman unload esetén (Windows appnál ez a legtöbb esetben csak az app leállításakor, kevesen használnak saját appdomaineket) esik ki belőle. Sok regex esetén ez memóriaszivárgásként észlelhető, amely során a private memory fogy (mivel a generált majd jittelt kód nem osztható meg).

Mindezek ellenére senkit nem akarok lebeszélni az előfordításról, mert tetemes gyorsulás érhető el vele, ha kevés fajta regexet kell lefuttatni hosszú bemenetre.

Regex legbelső párok keresésére

Monday, October 1st, 2007

Érdekes kérdés jött fel a devportálon.
Párokat kell keresni egy szövegben, de úgy, hogy a legbelső párokat találjuk meg.

Pl. begin end begin end, ebben két begin end-et kell találni, nem pedig egy nagyot, amiben benne van egy end begin.

A párost könnyű megfogni, amit nehezebb, hogy szűkítsük le a legkisebb halmazra a kifejezést.

Esetünkben úgy gondolkodhatunk, hogy begin aztán akármiből legalább egy majd end, és a kettő között nem lehet end. Ezzel megakadályozhatók az átlapolt eredmények.

A problémát a zero-width negative lookahead assertion tudja megoldani, amely “Continues match only if the subexpression does not match at this position on the right.”

Ez egy ilyen zero-width negative lookahead assertion izé: (?!end). Azt jelenti, hogy jobbról (azaz a ) után) nem lehet olyan, hogy end karakterek.

Azaz a példánkra: begin(.(?!end)).+?end

Ahhoz, hogy ez több sorra is menjen, a . értelmezését ki kell terjeszteni a \n-re is, .netben a Single Line mód biztosítja ezt.

Jó cikk a témában.