青山です。

On Sun, 18 Jun 2000 13:14:16 +0900,
kjana / os.xaxon.ne.jp (YANAGAWA Kazuhisa) wrote:

>   def expand!(tw = 8)
>     true while sub!(/(^|\n)([^\t\n]*)\t/) { $1+$2+" "*(tw-$2.size%tw) }
>   end
> 
> なんてのを多用してましたが,これは等価でしょうかね? どっちが効率いいの
> かわからないけど.

改行を含んだ文字列にも対応している、連続しているタブも1つ1つ展開して
いくという以外は、基本的に同じでしょうか。で、このような正規表現での複
数行対応も試してみたのですが、どうも、| のあたりがネックなのか、この書
き方だと遅くなるようなんですよね。

each_line, collect の方がずっと高速なので、そちらを使って複数行に対応
させた物を付けます。速度的には、上のタイプを expand.rb とすると、こん
な感じです。

$ time ruby expand.rb unexp > rexp1
real    0m2.885s   user    0m2.870s   sys     0m0.010s

$ time ruby -r text/tabs -e'print Text::Tabs::expand(ARGF.read)' unexp > rexp2
real    0m0.121s   user    0m0.100s   sys     0m0.020s


=begin

== EXPAND AND UNEXPAND TABS LIBRARY

text/tabs.rb

Version 0.2.0

Wakou Aoyama <wakou / fsinet.or.jp>

== EXAMPLE

  require "text/tabs"
  string_without_tabs = Text::Tabs::expand(string_with_tabs)
  string_with_tabs = Text::Tabs::unexpand(string_without_tabs)

  tabstop = 2
  string_without_tabs = Text::Tabs::expand(string_with_tabs, tabstop)
  string_with_tabs = Text::Tabs::unexpand(string_without_tabs, tabtsop)

=end


module Text
  module Tabs
    def Tabs::expand(string, tab_stop = 8)
      string.collect() do |line|
        cursor = 0
        line.gsub(/([^\t]*)(\t+)/) do
          cursor += Regexp::last_match[1].length
          add_space = Regexp::last_match[2].length * tab_stop
          add_space -= (cursor + add_space) % tab_stop
          cursor += add_space
          Regexp::last_match[1] + " " * add_space
        end
      end.join()
    end

    def Tabs::unexpand(string, tab_stop = 8)
      string.collect() do |line|
        Tabs::expand(line).gsub(/.{#{tab_stop}}/on) do |match|
          match.sub(/  +\z/, "\t")
        end
      end.join()
    end
  end
end


=begin

== HISTORY

* Sun Jun 18 23:31:44 JST 2000 - wakou
  * version 0.2.0
  * support for multiline string.

* 2000/06/18 03:20:45 - wakou
  * Text::Tabs::unexpand(): don't convert a single spece.

* 2000/06/18 00:06:20 - wakou
  * version 0.1.0 rerelease.
  * simple support for multibyte code.

* 2000/06/17 23:19:20 - wakou
  * version 0.1.0
  * first release.

$Date: 2000/06/18 14:37:30 $
=end


-- 
青山 和光 Wakou Aoyama <wakou / fsinet.or.jp>