2009-07-27 6 views
12

Existe-t-il un meilleur moyen de mettre en forme le texte de Twitter pour lier les hyperliens, le nom d'utilisateur et les hashtags? Ce que j'ai fonctionne mais je sais que cela pourrait être mieux fait. Je suis intéressé par les techniques alternatives. Je configure ceci en tant que HTML Helper pour ASP.NET MVC.Formatage du texte Twitter (TweetText) avec C#

using System; 
using System.Collections.Generic; 
using System.Text.RegularExpressions; 
using System.Web; 
using System.Web.Mvc; 

namespace Acme.Mvc.Extensions 
{ 

    public static class MvcExtensions 
    { 
     const string ScreenNamePattern = @"@([A-Za-z0-9\-_&;]+)"; 
     const string HashTagPattern = @"#([A-Za-z0-9\-_&;]+)"; 
     const string HyperLinkPattern = @"(http://\S+)\s?"; 

     public static string TweetText(this HtmlHelper helper, string text) 
     { 
      return FormatTweetText(text); 
     } 

     public static string FormatTweetText(string text) 
     { 
      string result = text; 

      if (result.Contains("http://")) 
      { 
       var links = new List<string>(); 
       foreach (Match match in Regex.Matches(result, HyperLinkPattern)) 
       { 
        var url = match.Groups[1].Value; 
        if (!links.Contains(url)) 
        { 
         links.Add(url); 
         result = result.Replace(url, String.Format("<a href=\"{0}\">{0}</a>", url)); 
        } 
       } 
      } 

      if (result.Contains("@")) 
      { 
       var names = new List<string>(); 
       foreach (Match match in Regex.Matches(result, ScreenNamePattern)) 
       { 
        var screenName = match.Groups[1].Value; 
        if (!names.Contains(screenName)) 
        { 
         names.Add(screenName); 
         result = result.Replace("@" + screenName, 
          String.Format("<a href=\"http://twitter.com/{0}\">@{0}</a>", screenName)); 
        } 
       } 
      } 

      if (result.Contains("#")) 
      { 
       var names = new List<string>(); 
       foreach (Match match in Regex.Matches(result, HashTagPattern)) 
       { 
        var hashTag = match.Groups[1].Value; 
        if (!names.Contains(hashTag)) 
        { 
         names.Add(hashTag); 
         result = result.Replace("#" + hashTag, 
          String.Format("<a href=\"http://twitter.com/search?q={0}\">#{1}</a>", 
          HttpUtility.UrlEncode("#" + hashTag), hashTag)); 
        } 
       } 
      } 

      return result; 
     } 

    } 

} 
+0

const chaîne HyperLinkPattern = @ "(http (s)?: // \ S +) \ s?"; // Support https aussi – NetProvoke

Répondre

3

C'est remarquablement similaire au code que j'ai écrit qui affiche mon statut Twitter sur mon blog. Les seules autres choses que je fais sont

1) en recherchant @name et en le remplaçant par <a href="http://twitter.com/name">Real Name</a>; 2) plusieurs @name à la suite reçoivent des virgules, s'ils ne les ont pas;

3) Les tweets commençant par @name(s) sont au format "To @name:".

Je ne vois aucune raison que cela ne puisse pas être un moyen efficace d'analyser un tweet - ils sont un format très cohérent (bon pour regex) et dans la plupart des situations la vitesse (millisecondes) est plus qu'acceptable.

Edit:

Here is the code for my Tweet parser. Il est un peu trop de temps pour mettre dans une réponse Stack Overflow. Il faut un tweet comme:

@ user1 @ utilisateur2 vérifier ce lien cool que je suis de @ user3: http://url.com/page.htm#anchor #coollinks

Et il se transforme en:

<span class="salutation"> 
    To <a href="http://twitter.com/user1">Real Name</a>, 
    <a href="http://twitter.com/user2">Real Name</a>: 
</span> check out this cool link I got from 
<span class="salutation"> 
    <a href="http://www.twitter.com/user3">Real Name</a> 
</span>: 
<a href="http://site.com/page.htm#anchor">http://site.com/...</a> 
<a href="http://twitter.com/#search?q=%23coollinks">#coollinks</a> 

Il a également enveloppe tout ce balisage dans un peu de JavaScript:

document.getElementById('twitter').innerHTML = '{markup}'; 

Ceci est ainsi le tweet fetcher peut fonctionner de manière asynchrone comme un JS et si Twitter est en panne ou lent, cela n'affectera pas le temps de chargement de la page de mon site.

+0

J'ai un problème avec mon code si une URL a un caractère de hachage. J'ai essayé d'utiliser \ b pour définir les limites des mots, mais cela ne fonctionne pas. Je ne suis pas sûr que l'exemple de Django fonctionnera pour moi en C# mais je l'essaie. – Brennan

+0

@ Brennan autant que je peux dire, les hashtags peuvent être alphanumériques. Capturez d'abord les URL (de cette façon, vous saisissez toutes les URL aveC#), puis exécutez votre regex de hashtag sur les fragments qui n'ont pas été récupérés par le remplaçant d'URL. –

+0

Je ne sais pas comment faire avec Regex en C#. Avez-vous un exemple? – Brennan

0

J'ai créé une méthode d'assistance pour raccourcir le texte à 140 caractères avec l'URL incluse. Vous pouvez définir la longueur du partage sur 0 pour exclure l'URL du tweet.

public static string FormatTwitterText(this string text, string shareurl) 
    { 
     if (string.IsNullOrEmpty(text)) 
      return string.Empty; 

     string finaltext = string.Empty; 
     string sharepath = string.Format("http://url.com/{0}", shareurl); 

     //list of all words, trimmed and new space removed 
     List<string> textlist = text.Split(' ').Select(txt => Regex.Replace(txt, @"\n", "").Trim()) 
           .Where(formatedtxt => !string.IsNullOrEmpty(formatedtxt)) 
           .ToList(); 

     int extraChars = 3; //to account for the two dots ".." 
     int finalLength = 140 - sharepath.Length - extraChars; 
     int runningLengthCount = 0; 
     int collectionCount = textlist.Count; 
     int count = 0; 
     foreach (string eachwordformated in textlist 
       .Select(eachword => string.Format("{0} ", eachword))) 
     { 
      count++; 
      int textlength = eachwordformated.Length; 
      runningLengthCount += textlength; 
      int nextcount = count + 1; 

      var nextTextlength = nextcount < collectionCount ? 
              textlist[nextcount].Length : 
              0; 

      if (runningLengthCount + nextTextlength < finalLength) 
       finaltext += eachwordformated; 
     } 

     return runningLengthCount > finalLength ? finaltext.Trim() + ".." : finaltext.Trim(); 
    } 
0

Il y a une bonne ressource pour l'analyse des messages Twitter ce lien, a fonctionné pour moi:

Comment Parse noms d'utilisateur Twitter, hashtags et URL en C# 3,0

http://jes.al/2009/05/how-to-parse-twitter-usernames-hashtags-and-urls-in-c-30/

Il contient le support pour:

  • urls
  • #hashtags
  • @usernames

BTW: Regex dans la méthode parseURL() a besoin d'examen, il analyse des symboles boursiers (BARC.L) en liens.