2009-07-27 13 views
12

¿Hay una mejor manera de dar formato al texto de Twitter para vincular los hipervínculos, nombre de usuario y hashtags? Lo que tengo funciona, pero sé que esto podría hacerse mejor. Estoy interesado en técnicas alternativas. Estoy configurando esto como un HTML Helper para ASP.NET MVC.Twitter (TweetText) con 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 string HyperLinkPattern = @ "(http (s)?: // \ S +) \ s?"; // Soporte https también – NetProvoke

Respuesta

3

Eso es notablemente similar al código que escribí que muestra mi estado de Twitter en mi blog. Las únicas cosas que más hago lo que hago son

1) mirando hacia arriba @name y su sustitución por <a href="http://twitter.com/name">Real Name</a>;

2) múltiples @name 's en una fila obtener comas, si es que no los tienen;

3) Tweets que comienzan con @name(s) se formatean "Para @Name:".

No veo ningún motivo para que no pueda ser una forma efectiva de analizar un tweet: son un formato muy consistente (bueno para expresiones regulares) y en la mayoría de las situaciones la velocidad (milisegundos) es más que aceptable.

Editar:

Here is the code for my Tweet parser. Es un poco demasiado tiempo para poner en una respuesta de desbordamiento de pila. Se necesita un tweet como:

@ usuario1 @ usuario2 echa un vistazo a este enlace interesante que recibí de @ User3: http://url.com/page.htm#anchor #coollinks

y lo convierte 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> 

También envuelve todo ese marcado en un pequeño JavaScript:

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

Esto es tan el buscador de tweets puede ejecutarse de forma asincrónica como un JS y si Twitter está inactivo o lento, no afectará el tiempo de carga de la página de mi sitio.

+0

Tengo un problema con mi código si una URL tiene un carácter hash. Intenté usar \ b para definir los límites de las palabras, pero eso no funciona. No estoy seguro si el ejemplo de Django funcionará para mí en C#, pero lo estoy probando. – Brennan

+0

@Brennan, por lo que puedo ver, los Hashtags pueden ser alfanuméricos. Capture las URL primero (de esa manera capta las URL con #), luego ejecute su hashtag regex en los fragmentos que no fueron recogidos por el sustituto de la URL. –

+0

No estoy seguro de cómo hacer eso con Regex en C#. ¿Tienes un ejemplo? – Brennan

0

creé método de ayuda para acortar el texto a 140 caracteres con url incluidos. Puede establecer la longitud de compartir en 0 para excluir url de 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

Hay un buen recurso para analizar los mensajes de Twitter este enlace, trabajó para mí:

Cómo analizar Twitter Los nombres de usuario, hashtags y URLs en C# 3,0

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

contiene soporte para:

  • Urls
  • #hashtags
  • @nombres de usuario

Por cierto: expresiones regulares en el parseURL() método debe revisarse, analiza los símbolos de acción (BARC.L) en enlaces.