De ce este această expresie regulată mai rapidă?

Scriu un client Telnet în C# și o parte din ceea ce trebuie să analizez sunt secvențele de evacuare ANSI / VT100, și anume doar cele folosite pentru culoare și formatare (detaliate aici ).

O metodă pe care o am este să găsesc toate codurile și să le elimin, astfel încât să pot reda textul fără formatare, dacă este necesar:

    
public static string StripStringFormating(string formattedString)
{
    if (rTest.IsMatch(formattedString))
        return rTest.Replace(formattedString, string.Empty);
    else
        return formattedString;
}

Sunt nou la expresii regulate și mi sa sugerat să folosesc acest lucru:

static Regex rText = new Regex(@"\e\[[\d;]+m", RegexOptions.Compiled);

Cu toate acestea, acest lucru a eșuat dacă codul de evacuare a fost incomplet din cauza unei erori la server. Deci, acest lucru a fost sugerat, dar prietenul meu a avertizat că ar putea fi mai lent (aceasta se potrivește, de asemenea, cu o altă condiție (z) pe care o voi întâlni mai târziu):

static Regex rTest = 
              new Regex(@"(\e(\[([\d;]*[mz]?))?)?", RegexOptions.Compiled);

Acest lucru nu numai că a funcționat, dar a fost de fapt mai rapid și a redus impactul asupra randării mele text. Poate cineva să explice unui începător regexp, de ce? :)

0
fr hi bn

4 răspunsuri

Fără a face o analiză detaliată, cred că este mai rapid din cauza semnelor de întrebare. Acestea permit ca expresia obișnuită să fie "leneșă" și să se oprească de îndată ce au suficient pentru a se potrivi, mai degrabă decât să verifice dacă restul de intrare se potrivește.

Nu sunt totuși complet mulțumit de acest răspuns, deoarece aceasta se aplică în majoritatea cazurilor la semnele de întrebare după * sau +. Dacă aș fi fost mai familiarizați cu contribuția, s-ar putea să aibă mai multă sens pentru mine.

(De asemenea, pentru formatul codului, puteți selecta întregul cod și apăsați Ctrl + K pentru a adăuga cele patru spații necesare.)

0
adăugat

Chiar vrei să faci rularea regexp de două ori? Fără a verifica (rău-mă) aș fi crezut că acest lucru ar funcționa bine:

public static string StripStringFormating(string formattedString)
{    
    return rTest.Replace(formattedString, string.Empty);
}

Dacă se întâmplă, ar trebui să vedeți că rulează ~ de două ori mai repede ...

0
adăugat
Gândindu-te acum, asta are sens, regexp rulează pe o linie fără potriviri este același lucru cu a rula mai întâi un cec pentru a vedea dacă se potrivește deloc. Veți obține același rezultat!
adăugat autor Nidonocu, sursa

Motivul pentru care numărul 1 este mai lent este că [\ d;] + este un cuantificator lacom. Cu +? sau *? se va face cuantificarea leneșă. Consultați MSDN - cuantificatori pentru mai multe informații.

Poate doriți să încercați:

"(\e\[(\d{1,2};)*?[mz]?)?"

Asta poate fi mai rapid pentru tine.

0
adăugat

Nu sunt sigur dacă acest lucru vă va ajuta cu ceea ce lucrați, dar cu mult timp în urmă am scris o expresie regulată pentru a analiza fișierele grafice ANSI.

(?s)(?:\e\[(?:(\d+);?)*([A-Za-z])(.*?))(?=\e\[|\z)

Acesta va returna fiecare cod și textul asociat cu acesta.

Șir de introducere:

[1;32mThis is bright green.[0m This is the default color.

Rezultate:

[ [1, 32], m, This is bright green.]
[0, m, This is the default color.]
0
adăugat
Vă mulțumim pentru acest răspuns, voi păstra această expresie la îndemână atunci când fără îndoială mă întorc și revizuiesc codul mai târziu pentru posibile îmbunătățiri. :) După cum am descoperit, regexpii "mai mari" tind să fie mai rapizi decât cei mai mici.
adăugat autor Nidonocu, sursa
De asemenea, mă interesează tot ce faci cu codurile ANSI din .NET. În prezent, reeducarea site-ului meu în șine, mai degrabă decât .NET, dar sunt întotdeauna curios să văd cum pot oamenii să folosească .NET pentru interpretarea ANSI.
adăugat autor lordscarlet, sursa