strscan.so

このライブラリについて

strscan は文字列スキャナライブラリです。簡単に高速な スキャナを記述できます。以下に使用例を示します。

s = StringScanner.new('This is an example string')
s.eos?            #=> false

p s.scan(/\w+/)   #=> "This"
p s.scan(/\w+/)   #=> nil
p s.scan(/\s+/)   #=> " "
p s.scan(/\s+/)   #=> nil
p s.scan(/\w+/)   #=> "is"
s.eos?            #=> false

p s.scan(/\s+/)   #=> " "
p s.scan(/\w+/)   #=> "an"
p s.scan(/\s+/)   #=> " "
p s.scan(/\w+/)   #=> "example"
p s.scan(/\s+/)   #=> " "
p s.scan(/\w+/)   #=> "string"
s.eos?            #=> true

p s.scan(/\s+/)   #=> nil
p s.scan(/\w+/)   #=> nil

一言で言うと StringScanner オブジェクトはスキャンする文字列と 「スキャンポインタ」のセットです。スキャンポインタとはスキャン しおわったところを示すインデックスのことです。最初スキャンポインタは 文字列先頭にあり、その地点でのみマッチを試します。マッチしたら その後ろにポインタを進めます。

## a string and a scan pointer   ("_" = scan pointer)

s = StringScanner.new('This is an example string')
_This is an example string     s.eos? = false
s.scan(/\w+/)
This_ is an example string     s.eos? = false
s.scan(/\s+/)
This _is an example string     s.eos? = false
s.scan(/\w+/)
This is_ an example string     s.eos? = false
s.scan(/\s+/)
This is _an example string     s.eos? = false
s.scan(/\w+/)
This is an_ example string     s.eos? = false
s.scan(/\s+/)
This is an _example string     s.eos? = false
s.scan(/\w+/)
This is an example_ string     s.eos? = false
s.scan(/\s+/)
This is an example _string     s.eos? = false
s.scan(/\w+/)
This is an example string_     s.eos? = true

警告

StringScanner は $~ $& $1 $2 …… などの正規表現関連変数を セットしません。代わりに StringScanner#[], matched? などの マッチデータ関連メソッドを使ってください。

class StringScanner

Class Methods

new( str: String, dup: bool = true ) -> StringScanner

新しい StringScanner オブジェクトを生成します。str はスキャン対 象の文字列です。dup が true の時は複製したうえで使います。またど ちらの場合でも StringScanner が保持する文字列はfreeze されます。

Instance Methods

scan( pattern: Regexp ) -> String

スキャンポインタの地点だけで pattern と文字列のマッチを試します。 マッチしたら、スキャンポインタを進めて正規表現にマッチした 部分文字列を返します。マッチしなかったら nil を返します。

s = StringScanner.new('test string')
p s.scan(/\w+/)   #=> "test"
p s.scan(/\w+/)   #=> nil
p s.scan(/\s+/)   #=> " "
p s.scan(/\w+/)   #=> "string"
p s.scan(/./)     #=> nil
skip( pattern: Regexp ) -> Integer

スキャンポインタの地点だけで PATTERN と文字列のマッチを試します。 マッチしたらスキャンポインタを進めマッチした部分文字列の 長さを返します。マッチしなかったら nil を返します。

s = StringScanner.new('test string')
p s.skip(/\w+/)   #=> 4
p s.skip(/\w+/)   #=> nil
p s.skip(/\s+/)   #=> 1
p s.skip(/\w+/)   #=> 6
p s.skip(/./)     #=> nil
match?( pattern: Regexp ) -> Integer

スキャンポインタの地点だけで PATTERN と文字列のマッチを試します。 マッチしたら、スキャンポインタは進めずにマッチした 部分文字列の長さを返します。マッチしなかったら nil を 返します。

s = StringScanner.new('test string')
p s.match?(/\w+/)   #=> 4
p s.match?(/\w+/)   #=> 4
p s.match?(/\s+/)   #=> nil
getch -> String

一文字スキャンして返します。 スキャンポインタをその後ろに進めます。

get_byte -> String

一バイトスキャンして文字列で返します。 スキャンポインタをその後ろに進めます。

peek( len: Integer ) -> String

スキャンポインタから長さ len バイト分だけ文字列を返します。

eos? -> bool

スキャンポインタが文字列の末尾を指しているとき真。

string -> String

スキャン対象にしている文字列それ自体です。freeze されています。

matched? -> bool

前回のマッチが成功していたら真。

pre_match -> String

前回マッチを行った文字列のうち、マッチしたところよりも前の 部分文字列を返します。前回のマッチが失敗していると常に nil を 返します。

post_match -> String

前回マッチを行った文字列のうち、マッチしたところよりも後ろの 部分文字列を返します。前回のマッチが失敗していると常に nil を 返します。

self[ n: Integer ] -> String

前回マッチした正規表現の n 番目のかっこに対応する部分文字列を返 します。インデックス 0 はマッチした部分全体です。前回のマッチが 失敗していると常に nil を返します。

matched -> String

前回マッチした部分文字列を返します。

reset

スキャンポインタを文字列先頭 (インデックス 0 ) に戻し、 マッチ記録を捨てます。

terminate

スキャンポインタを文字列末尾後まで進め、マッチ記録を捨てます。

unscan

スキャンポインタを前回のマッチの前の位置に戻します。 一回分以上は戻せません。前回のマッチが失敗していると 例外 ScanError が発生します。