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? などの マッチデータ関連メソッドを使ってください。
新しい StringScanner オブジェクトを生成します。str はスキャン対 象の文字列です。dup が true の時は複製したうえで使います。またど ちらの場合でも StringScanner が保持する文字列はfreeze されます。
スキャンポインタの地点だけで 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
スキャンポインタの地点だけで 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
スキャンポインタの地点だけで PATTERN と文字列のマッチを試します。 マッチしたら、スキャンポインタは進めずにマッチした 部分文字列の長さを返します。マッチしなかったら nil を 返します。
s = StringScanner.new('test string') p s.match?(/\w+/) #=> 4 p s.match?(/\w+/) #=> 4 p s.match?(/\s+/) #=> nil
一文字スキャンして返します。 スキャンポインタをその後ろに進めます。
一バイトスキャンして文字列で返します。 スキャンポインタをその後ろに進めます。
スキャンポインタから長さ len バイト分だけ文字列を返します。
スキャンポインタが文字列の末尾を指しているとき真。
スキャン対象にしている文字列それ自体です。freeze されています。
前回のマッチが成功していたら真。
前回マッチを行った文字列のうち、マッチしたところよりも前の 部分文字列を返します。前回のマッチが失敗していると常に nil を 返します。
前回マッチを行った文字列のうち、マッチしたところよりも後ろの 部分文字列を返します。前回のマッチが失敗していると常に nil を 返します。
前回マッチした正規表現の n 番目のかっこに対応する部分文字列を返 します。インデックス 0 はマッチした部分全体です。前回のマッチが 失敗していると常に nil を返します。
前回マッチした部分文字列を返します。
スキャンポインタを文字列先頭 (インデックス 0 ) に戻し、 マッチ記録を捨てます。
スキャンポインタを文字列末尾後まで進め、マッチ記録を捨てます。
スキャンポインタを前回のマッチの前の位置に戻します。 一回分以上は戻せません。前回のマッチが失敗していると 例外 ScanError が発生します。