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 はスキャン対象の文字列です。
Ruby 1.8.0 では、dup が true の時は文字列を複製して freeze します。 dup が false なら複製せずに freeze します。
Ruby 1.8.1 以降では dup は単に無視します。 引数の文字列は複製も 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
一文字スキャンして返します。 一文字の定義は$KCODEに依存します。 スキャンポインタをその後ろに進めます。
$KCODE に関らず一バイトスキャンして文字列で返します。 スキャンポインタをその後ろに進めます。
スキャンポインタから長さ bytes バイト分だけ文字列を返します。
スキャンポインタが行頭を指しているとき真。 行頭の定義は、文字列先頭かまたは \n の直後を指していることです。 文字列末尾は必ずしも行頭ではありません。
Ruby 1.8.1 以降でのみ定義されています。
スキャンポインタが文字列の末尾を指しているとき真。
前回のマッチが成功していたら真。
スキャン対象にしている文字列それ自体です。 Ruby 1.8.0 では freeze されています。
なお、現在の実装は常に StringScanner.new に渡した文字列を 返しますが、この仕様が将来に渡って保証されるわけではありません。
また 1.8.1 以降では返り値の文字列に対して破壊的な変更もできますが、 この操作がスキャン対象の文字列を変更することも保証されません。
self を返します*1
操作対象の文字列に対し str を破壊的に連結します。 マッチ記録は変更されません。 この操作は StringScanner.new に渡した文字列にも影響することがあります。
Ruby 1.8.1 以降でのみ定義されます。
前回マッチを行った文字列のうち、マッチしたところよりも前の 部分文字列を返します。前回のマッチが失敗していると常に nil を 返します。
前回マッチを行った文字列のうち、マッチしたところよりも後ろの 部分文字列を返します。前回のマッチが失敗していると常に nil を 返します。
前回マッチした部分文字列を返します。
前回マッチした正規表現の n 番目のかっこに対応する部分文字列を返 します。インデックス 0 はマッチした部分全体です。前回のマッチが 失敗していると常に nil を返します。
現在のスキャンポインタのインデックスを返します。
スキャンポインタのインデックスを n にセットし、マッチ記録を捨てます。 n はバイト単位です。
スキャンポインタを文字列先頭 (インデックス 0) に戻し、 マッチ記録を捨てます。
スキャンポインタを文字列末尾後まで進め、マッチ記録を捨てます。
スキャンポインタを前回のマッチの前の位置に戻します。 一回分以上は戻せません。前回のマッチが失敗していると 例外 ScanError が発生します。
*1多分。