2008-02-07 [長年日記]
λ. 正規表現における非包含オペレータの提案 by 田中哲
を読んだ。天泣記 (2008-01-11) より。いつもながらakrさんのこういうセンスは羨ましい。
これが役に立つ例はいくらでもあるとは思うが、最近遭遇したものだと「プレーンテキストをHTMLに変換する際にURLをアンカーにする」処理が直観的に書けそうだと思った。
実際に書いたコード:
def text2html(s)
re = URI.regexp
result = ''
while m = re.match(s)
result << CGI.escapeHTML(m.pre_match)
uri = CGI.escapeHTML(m.to_s)
result << %Q[<a href="#{uri}">#{uri}</a>]
s = m.post_match
end
result << CGI.escapeHTML(s)
result
end
非包含オペレータがあるとこう書けそう:
def text2html(s)
s.gsub(/(#{URI.regexp})|!(?:#{URI.regexp})/) {
if $1
uri = CGI.escapeHTML($1)
%Q[<a href="#{uri}>#{uri}</a>]
else
CGI.escapeHTML($2)
end
}
end
おまけにtDiaryのString#make_linkのコード。 スペースやタブの処理もあるので単純に比較はできないけど、なんというか……
class String
def make_link
r = %r<(((http[s]{0,1}|ftp)://[\(\)%#!/0-9a-zA-Z_$@.&+-,'"*=;?:~-]+)|([0-9a-zA-Z_.-]+@[\(\)%!0-9a-zA-Z_$.&+-,'"*-]+\.[\(\)%!0-9a-zA-Z_$.&+-,'"*-]+))>
return self.
gsub( / /, "\001" ).
gsub( /</, "\002" ).
gsub( />/, "\003" ).
gsub( /&/, '&' ).
gsub( /\"/, "\004").
gsub( r ){ $1 == $2 ? "<a href=\"#$2\">#$2</a>" : "<a href=\"mailto:#$4\">#$4</a>" }.
gsub( /\004/, '"' ).
gsub( /\003/, '>' ).
gsub( /\002/, '<' ).
gsub( /^\001+/ ) { $&.gsub( /\001/, ' ' ) }.
gsub( /\001/, ' ' ).
gsub( /\t/, ' ' * 8 )
end
end
[ツッコミを入れる]
