2010-10-14 8 views
2

Je suis l'analyse d'une balise image de code BB:C# Regex.Replace(): obtenir les valeurs

[img] http://imagesource.com [/ img]

I utilise la fonction Replace() suivante:

Regex.Replace(msg, @"\[img\]([^\]]+)\[\/img\]", @"<img src=""$1"" border=""0"" />", RegexOptions.IgnoreCase); 

Et j'ai besoin d'obtenir l'URL lors de l'analyse. J'ai besoin de connaître la valeur de "$ 1". C'est possible? La classe Regex remplace en quelque sorte la chaîne "$ 1" par la valeur dont j'ai besoin, donc il doit y avoir un moyen de l'obtenir.

+0

L'analyse de bbcode avec regex présente les mêmes inconvénients que l'analyse de code HTML avec regex, car les deux langues ne sont pas les mêmes. Voir http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 Vous devriez vous pencher sur l'utilisation d'un analyseur bbcode (une recherche google rapide trouvé http: //bbcode.codeplex.com/ par exemple) –

Répondre

6

Il semble que vous cherchiez la méthode Replace avec une surcharge qui accepte un MatchEvaluator. La page MSDN de cette méthode peut être trouvée here.

Essayez ceci:

string input = "[img]http://imagesource.com[/img]"; 
string pattern = @"\[img]([^\]]+)\[\/img]"; 
string result = Regex.Replace(input, pattern, m => 
    { 
     var url = m.Groups[1].Value; 
     // do something with url here 
     // return the replace value 
     return @"<img src=""" + url + @""" border=""0"" />"; 
    }, 
    RegexOptions.IgnoreCase); 

Il utilise un lambda à plusieurs instructions pour simplifier le travail avec le groupe et effectuer plus de logique avant de retourner la valeur de remplacement. Vous pouvez, bien sûr, sortir avec ce lieu:

string result = Regex.Replace(input, pattern, 
    m => @"<img src=""" + m.Groups[1].Value + @""" border=""0"" />", 
    RegexOptions.IgnoreCase); 

Dans le cas ci-dessus, il n'y a pas besoin pour le return mais il est juste de retourner la chaîne d'origine sans évaluation supplémentaire. Vous pouvez coller quelques opérateurs ternaires et ajouter cette logique, mais cela aura l'air désordonné. Un lambda multi-déclaration est beaucoup plus propre. Vous pouvez envisager de le décomposer dans sa propre méthode, comme indiqué dans le lien MSDN mentionné ci-dessus, si elle est trop grande ou sera réutilisée dans d'autres efforts Regex.Replace.

BTW, j'ai également simplifié votre modèle légèrement en supprimant les évasions pour ]. Seule l'ouverture [ doit être échappée.

+0

Incroyable! C'est exactement ce dont j'ai besoin. Je vous remercie! – Alex

+1

On dirait que le premier groupe contient toute la chaîne, c'est pourquoi il a utilisé m.Groups [1] – reggaeguitar

+0

@reggaeguitar c'est correct. Le groupe à l'index 0 contient la correspondance entière. –

0

Pour conserver la chaîne capturée, il suffit de "capturer" la valeur de retour.

string s = Regex.Replace(msg, @"\[img\]([^\]]+)\[\/img\]", @"<img src=""$1"" border=""0"" />", RegexOptions.IgnoreCase); 
+0

Mais cela retourne tout ... – Alex

0

groupes de capture sont disponibles dans la propriété Capture pour le match Regex, si vous faites un match au lieu d'un remplacement, vous aurez accès au groupe.

+0

J'ai essayé d'utiliser "r.Match (text) .Groups [0]" mais cela n'a pas fonctionné – Alex

+0

Désolé, j'ai listé le propriété. La propriété Captures possède tous les groupes de capture. Les groupes sont les groupes Capture nommés. S'il n'y en a pas, alors Groups [0] est la dernière capture correspondante. –

Questions connexes