2010-04-13 5 views
1

J'essaie de remplacer un modèle d'URL convivial par une notation d'URL html mais en raison du manque d'expérience regex je n'arrive pas à comprendre pourquoi mon regex ne remplace que la première occurrence de mon motif :Regex.Replace ne remplace que le début de la chaîne

string text = "[Hotel Des Terrasses \http://flash-hotel.fr/] and [Du Phare \http://www.activehotels.com/hotel/]"; 
text = Regex.Replace(text, @"\[(.+)\s*\\(.+)\]", "<a href=\"$2\" target=\"_blank\">$1</a>"); 

Comment puis-je remplacer le deuxième modèle par le balisage HTML?

Répondre

4

Votre expression régulière traite la chaîne entière comme une seule correspondance. Essayez d'utiliser (.+?) au lieu de (.+) (les deux instances).

+1

Ceci est la bonne réponse. (Vous devez changer les deux '. +' 'S) – SLaks

+0

Merci pour le qualificatif, @SLaks. –

+0

génial merci! –

2

En note de côté, vous pourriez vouloir considérer l'abus potentiel de ceci. Vous devriez probablement effectuer:

 StringBuilder sb = new StringBuilder(); 
     int pos = 0; 

     Regex exp = new Regex(@"\[(.+?)\s*\\(.+?)\]"); 
     foreach (Match m in exp.Matches(text)) 
     { 
      sb.Append(text, pos, m.Index - pos); 
      pos = m.Index + m.Length; 

      Uri tmp; 
      if(Uri .TryCreate(m.Groups[2], UriKind.Absolute, out tmp)) 
      { 
       sb.AppendFormat("<a href=\"{0}\" target=\"_blank\">{1}</a>", 
        System.Web.HttpUtility.HtmlAttributeEncode(tmp.AbsoluteUri), 
        System.Web.HttpUtility.HtmlEncode(m.Groups[1]) 
        ); 
      } 
     } 
     sb.Append(text, pos, text.Length - pos); 

Note: Vous ne savez pas des indices de groupe, j'utiliser des groupes nommés dans le reg-ex. Avez-vous essayé un outil regex comme Expresso?

+0

Ce n'est pas le problème. ('Regex.Replace' remplace _all_ matches) – SLaks

+0

N'étant pas sûr que je n'utilise pas la version statique du remplacement, je vais le mettre à jour. –

+0

merci pour la suggestion, bonne idée. Mais dans mon scénario pas nécessaire car ce n'est pas l'entrée web. –

1

L'expression régulière prend la plus longue match, qui dans ce cas est la chaîne entière, parce que vos conditions qu'il commence par un [, se termine par un ] et a au moins une barre oblique inverse quelque part entre les deux. Re-spécifier l'expression régulière afin de ne pas autoriser un autre ] à l'intérieur des crochets, par ex. utilisez [^\]] au lieu de . (les deux occurrences).

+0

Ceci est aussi la bonne réponse. – SLaks

Questions connexes