strscan の使い方


警告

strscan には C 版と Ruby 版があります。Ruby 版は C 版と似た動作を しますが、根本的に原理が違います。必ずこのページ最後にある違いの 説明を読んでから使ってください。

基本的な使い方

以下に簡単な例を示します。


sc = StringScanner.new( string )
while sc.rest? do
  sc.skip /\A\s+/
  if tmp = sc.scan( /\A\w+/ ) then
    puts tmp
  end
end

このコードは、文字列から単語を切りだし、それを表示します。
StringScanner は文字列と「どこまでスキャンしたか」を示すポインタがセットに なったようなオブジェクトで、正規表現とのマッチをおこなってそのポインタを 進めていくことでスキャンを行います。

StringScanner の重要なメソッドは 3 つです。
scan は最も重要なメソッドで、与えられた正規表現がマッチする部分を切り出して 返します。skip はマッチした部分の先にポインタを進めるだけで、真偽値を返します。 empty? はポインタが最後までいったかどうかを真偽値で返すメソッドです。 rest? はその反対です。

scan を使った場合、どんな正規表現でも文字列の先頭にのみ マッチします。たとえば、/string/ の場合、先頭に 'string' という 文字列がある場合のみマッチします。これは、内部で使う関数が Ruby の デフォルトと違うからです。通常の Ruby の正規表現のような挙動をさせるには、 scan_until などの until 系メソッドを使います。

ただし、until 系メソッドでも文字列の途中だけを スキャンすることはできません。例えば次のような場合は、


s = StringScanner.new( "word1   word2" )
ret = s.scan_until( /\s+/ )

ret は "word1 " となり " " にはなりません。

Ruby 版 strscan について

拡張モジュールをコンパイルできない場所でも使いたいという理由から、 strscan には Ruby バージョンも用意されています。しかし Ruby バージョンは根本的なところに違いがあります。最重要なのは scan, skip などのメソッドに渡す正規表現が \A で始まっている必要があることです。 また scan_until など until 系メソッドには \A 以外で始まる正規表現を 渡さないと動きません。両方のメソッドを使う場合は、拡張モジュール版と Ruby 版は完全に別物だと考えたほうがよいでしょう。

また巨大な文字列に対して Ruby 版を使うと異常に動作が遅くなります。 これは実装上どうしようもありません。

Ruby バージョンが使われているかどうかは StringScanner.name を見て みればわかります。StringScanner_C となれば C 版で、StringScanner_R なら Ruby 版です。


Copyright (c) 1999-2001 Minero Aoki <aamine@loveruby.net>