[[ネタ記録庫/Scala/dispatch]] *文字列に含まれるURLをリンクタグにしたり、@で始まる文字列をTwitterアカウントへのリンクタグにしたりしてNodeSeqで返す [#a1b4237e] pomu0325さんのブログ記事のコードを拡張してみた。 - 元ネタ: [[文字列に含まれるURLをaタグにしてNodeSeqで返す - pomu0325:http://pomu0325.blogspot.com/2010/03/scala-urlanodeseq.html]] 格調で追加したのは次の二つ - @で始まる文字列をtwitterアカウントへのリンクタグに変換 - #で始まる文字列をtwitterのハッシュタグに変換 効率は知らない。 def linkURL(s: String): NodeSeq = { import util.matching._ class FirstMatch(pattern: Regex) { def c2s(c: CharSequence): String = c.toString def unapply(s: String) = pattern.findFirstMatchIn(s) map { case m => (c2s(m.before), m.matched, c2s(m.after)) } } val link = new FirstMatch("""http://[\d\w\-\./%?=#]+""".r) val reply = new FirstMatch("""@[a-zA-Z0-9]+""".r) val hashtag = new FirstMatch("""#[a-zA-Z0-9]+""".r) s match { case link(before, s, after) => linkURL(before) ++ <a href={s}>{xml.Text(s)}</a> ++ linkURL(after) case reply(before, s, after) => val href = "http://twitter.com/"+s.drop(1) linkURL(before) ++ <a href={href}>{xml.Text(s)}</a> ++ linkURL(after) case hashtag(before, s, after) => val href = "/?q="+Helpers.urlEncode(s) linkURL(before) ++ <a href={href}>{xml.Text(s)}</a> ++ linkURL(after) case s => xml.Text(s) } } これはさらに次のように拡張できる。次の例はTwitterのAPIが返す文字列がhtmlエンコードされているのを安全に戻している。 def linkURL(s: String): NodeSeq = { import util.matching._ class FirstMatch(pattern: Regex) { def c2s(c: CharSequence): String = c.toString def unapply(s: String) = pattern.findFirstMatchIn(s) map { case m => (c2s(m.before), m.matched, c2s(m.after)) } } val link = new FirstMatch("""http://[\d\w\-\./%?=#]+""".r) val reply = new FirstMatch("""@[a-zA-Z0-9]+""".r) val hashtag = new FirstMatch("""#[a-zA-Z0-9]+""".r) val amp = new FirstMatch("&".r) val lt = new FirstMatch("<".r) val gt = new FirstMatch(">".r) val quote = new FirstMatch(""".r) s match { case link(before, s, after) => linkURL(before) ++ <a href={s}>{xml.Text(s)}</a> ++ linkURL(after) case reply(before, s, after) => val href = "http://twitter.com/"+s.drop(1) linkURL(before) ++ <a href={href}>{xml.Text(s)}</a> ++ linkURL(after) case hashtag(before, s, after) => val href = "/?q="+Helpers.urlEncode(s) linkURL(before) ++ <a href={href}>{xml.Text(s)}</a> ++ linkURL(after) case lt(before,_,after) => linkURL(before) ++ xml.Text("<") ++ linkURL(after) case gt(before,_,after) => linkURL(before) ++ xml.Text(">") ++ linkURL(after) case quote(before,_,after) => linkURL(before) ++ xml.Text("\"") ++ linkURL(after) case amp(before,_,after) => linkURL(before) ++ xml.Text("&") ++ linkURL(after) case s => xml.Text(s) } }