2009-07-27 2 views
12

트위터의 텍스트를 하이퍼 링크, 사용자 이름, 해시 태그와 연결하는 더 좋은 방법이 있습니까? 내가 가진 것은 일하고 있지만 이것이 더 잘할 수 있다는 것을 알고있다. 나는 대체 기술에 관심이 있습니다. 이 설정은 ASP.NET MVC 용 HTML 도우미로 설정됩니다.C#으로 트위터 텍스트 (TweetText) 포맷하기

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?"; // https도 지원 – NetProvoke

답변

3

내 블로그에 트위터 상태를 표시하는 코드와 매우 흡사합니다. 내가 할 수있는 유일한 추가 작업은

입니다. 1) @name을 찾아서 <a href="http://twitter.com/name">Real Name</a>으로 바꿉니다.

2) 행의 복수형 @name은 쉼표를 갖습니다.

3) @name(s)으로 시작하는 트윗은 "To @name :"형식으로되어 있습니다.

트윗을 구문 분석하는 데 효과적인 방법이 될 수없는 이유가 없습니다. 매우 일관된 형식 (정규 표현식에 적합)이고 대부분의 경우 속도 (밀리 초)가 허용 가능 이상입니다.

편집 :

Here is the code for my Tweet parser. 그것은 스택 오버플로 대답에 넣어 너무 오래 조금이다. 이 같은 트윗을 취

@ USER1 @ 사용자 2 내가 @의 사용자 3에서 가져온이 멋진 링크를 체크 아웃 : http://url.com/page.htm#anchor #coollinks

을 그리고로 바뀝니다 : 또한

<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> 

이 약간의 자바 스크립트에서 모든 마크 업을 감싼다.

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

이것은 매우 트위터 가져 오기 프로그램은 JS처럼 비동기 적으로 실행될 수 있으며 트위터가 다운되었거나 느리면 내 사이트의 페이지로드 시간에는 영향을 미치지 않습니다.

+0

URL에 해시 문자가 있으면 코드에 문제가 있습니다. 단어 경계를 정의하기 위해 \ b를 사용했지만 작동하지 않습니다. Django 예제가 C#에서 작동하는지 잘 모르겠지만 시도하고 있습니다. – Brennan

+0

@ 브레넌 내가 말할 수있는 한, 해시 태그는 영숫자 일 수 있습니다. 먼저 URL을 캡처하여 (#을 사용하여 URL을 잡은 다음) URL 대체 자에 의해 선택되지 않은 조각에 대해 해시 태그 정규식을 실행하십시오. –

+0

C#에서 Regex를 사용하여이를 수행하는 방법을 잘 모르겠습니다. 모범이 있습니까? – Brennan

0

URL이 포함 된 텍스트를 140 자로 단축하는 도우미 메서드를 만들었습니다. 공유 길이를 0으로 설정하여 짹짹에서 URL을 제외 할 수 있습니다. 트위터 메시지에이 링크를 구문 분석을위한 좋은 자원이있다

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(); 
    }