Regular expressions…!
Friday, October 30th, 2009Autor: cesar.silva
Há relativamente pouco tempo atrás, pediram-me para incluir em dada página de um dos nossos clientes uma secção que fosse buscar tweets de uma dada conta. Como seria de esperar encontrei no site do Twitter informação sobre as libraries existentes para C# e depois de alguma leitura acabei por utilizar aquela que me pareceu melhor ir de encontro às minhas necessidades, que foi o TweetSharp. O site por si já faz um excelente trabalho a explicar como a API funciona pelo que não vou perder muito tempo com isso.
Fiz o que tinha a fazer e reparei que a estrutura de cada tweet vinha com a propriedade Text, sem qualquer tipo de formatação (e ainda bem), o que me fez deparar com uma necessidade: como formatar os links dos tweets?! Como já devem ter visto, cada tweet pode conter referências a @users, #trends ou http://weblinks, e como tal costumam ser links.
Para mim tornou-se claro que este era um problema a ser resolvido com regular expressions.
Geek Stuff!
As regular expressions permitem-nos procurar padrões em variáveis de texto e determinar se pretendemos executar acções sobre as mesmas caso esse mesmo padrão seja encontrado. Para isso, utilizamos a classe Regex.
Para efeito de exemplo, criei a classe TweetFormatter com o método Twitterize que converte a esta variável RawTweet num tweet formatado com links.
RawTweet = "@csilva parece que o @rfiel andou a comentar sobre #silverlight ultimamente. Mais informações em http://silverlight.net/"; Tweet = TweetFormatter.Twitterize(RawTweet);
Utilizando o método Replace da classe Regex, conseguimos substituir todas as ocorrências que obedeçam ao padrão por nós definido através de uma regular expression, por uma expressão por nós definida através de um MatchEvaluator, que não é nada mais que um delegate que recebe o Match encontrado na expressão original.
internal static string Twitterize(string rawTweet) { // Return the tweet itself if null or empty if(String.IsNullOrEmpty(rawTweet)) return rawTweet; // Replace all the user links var twitterUserRegex = new Regex(@"(?<startPattern>(^|[^a-z0-9])@)(?<twitterUser>\w+)"); var resultTweet = twitterUserRegex.Replace(rawTweet, TwitterUserEvaluator); // Replace all the trend links var twitterTrendRegex = new Regex(@"(?<startPattern>(^|\s))\#(?<twitterTrend>\w+)"); resultTweet = twitterTrendRegex.Replace(resultTweet, TwitterTrendEvaluator); return resultTweet; }
Com efeito, reparem que estou a utilizar 2 métodos diferentes, para determinar a expressão pela qual um @user ou uma #trend serão substituídos.
private static string TwitterUserEvaluator(Match currentMatch) { var userTwitterLink = String.Format("{0}<a href=\"http://twitter.com/{1}\" target=\"_blank\">{1}</a>", currentMatch.Groups["startPattern"], currentMatch.Groups["twitterUser"]); return userTwitterLink; } private static string TwitterTrendEvaluator(Match currentMatch) { var userTwitterLink = String.Format("{0}<a href=\"http://twitter.com/#search?q=%23{1}\" target=\"_blank\">#{1}</a>", currentMatch.Groups["startPattern"], currentMatch.Groups["twitterTrend"]); return userTwitterLink; }
Para quem quiser os ficheiros com a implementação deste exercício, pode retirá-los em Source Code.
Wicked Tools!
Para quem não conhecer fica aqui a sugestão: existe uma ferramenta muito boa não só para testar como para aprender a trabalhar com regular expressions que se chama Expresso e foi desenvolvida pela Ultrapico.