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? :)
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.)
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.
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 ...
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.]