2008-08-07 28 views
15

J'écris un client Telnet de sortes en C# et une partie de ce que j'ai à analyser sont des séquences d'échappement ANSI/VT100, spécifiquement, seulement celles utilisées pour la couleur et le formatage (détaillé here).Pourquoi cette expression régulière est-elle plus rapide?

Une méthode que j'ai un pour trouver tous les codes et les enlever, donc je peux rendre le texte sans mise en forme si nécessaire:

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

Je suis nouveau à des expressions régulières et je suggéré utilisez ceci:

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

Cependant, cela a échoué si le code d'échappement était incomplète en raison d'une erreur sur le serveur. Alors cela a été suggéré, mais mon ami a averti qu'il pourrait être plus lent (celui-ci correspond également à une autre condition (z) que je pourrais rencontrer plus tard):

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

Ce non seulement travaillé, mais était en fait plus rapide à et réduit l'impact sur mon rendu de texte. Quelqu'un peut-il expliquer à un débutant regexp, pourquoi? :)

Répondre

1

Sans faire une analyse détaillée, je suppose que c'est plus rapide à cause des points d'interrogation. Ils permettent à l'expression régulière d'être "paresseux" et s'arrêtent dès qu'ils en ont assez pour correspondre, plutôt que de vérifier si le reste de l'entrée correspond.

Je ne suis pas entièrement satisfait de cette réponse, car cela s'applique principalement aux points d'interrogation après * ou +. Si je connaissais mieux l'apport, cela pourrait me sembler plus logique.

(En outre, pour la mise en forme de code, vous pouvez sélectionner tous de votre code et appuyez sur Ctrl + K pour l'avoir ajouter les quatre espaces nécessaires.)

3

La raison pour laquelle # 1 est plus lent est que [\ d;] + est un quantificateur gourmand. En utilisant +? ou *? va faire de la quantification paresseuse. Voir MSDN - Quantifiers pour plus d'informations.

Vous pouvez essayer:

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

Cela peut être plus rapide pour vous.

3

Voulez-vous vraiment exécuter deux fois l'expression rationnelle? Sans avoir vérifié (mauvais moi) j'aurais pensé que cela fonctionnerait bien:

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

Si oui, vous devriez le voir courir ~ deux fois plus vite ...

+0

En y repensant maintenant, qui ne fait sens, l'exécution d'une expression rationnelle sur une ligne sans matchs est le même que l'exécution d'un premier chèque à voir si cela correspond du tout. Vous obtenez le même résultat! – Nidonocu

1

Je ne sais pas si Cela aidera avec ce que vous travaillez, mais il y a longtemps, j'ai écrit une expression régulière pour analyser les fichiers graphiques ANSI.

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

Il retournera chaque code et le texte qui lui est associé.

Chaîne d'entrée:

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

Résultats:

[ [1, 32], m, This is bright green.] 
[0, m, This is the default color.] 
+0

Merci pour cette réponse, je garderai cette expression à portée de main quand je reviendrai sans doute en revue et réviser le code plus tard pour d'éventuelles améliorations. :) Comme je l'ai découvert, les expressions rationnelles «plus grandes» ont tendance à être plus rapides que les expressions plus petites. – Nidonocu

+0

Je suis également intéressé par tout ce que vous faites avec les codes ANSI dans .NET. Je suis actuellement en train de refaire mon site en rails plutôt que .NET, mais je suis toujours curieux de voir comment les gens sont en mesure d'exploiter .NET pour interpréter ANSI. – lordscarlet