トップ «前の日記(2008-02-06) 最新 次の日記(2008-02-09)» 月表示 編集

日々の流転


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( /&/, '&amp;' ).
                        gsub( /\"/, "\004").
                        gsub( r ){ $1 == $2 ? "<a href=\"#$2\">#$2</a>" : "<a href=\"mailto:#$4\">#$4</a>" }.
                        gsub( /\004/, '&quot;' ).
                        gsub( /\003/, '&gt;' ).
                        gsub( /\002/, '&lt;' ).
                        gsub( /^\001+/ ) { $&.gsub( /\001/, '&nbsp;' ) }.
                        gsub( /\001/, ' ' ).
                        gsub( /\t/, '&nbsp;' * 8 )
        end
end
Tags: 論文