class StringScanner

[edit]

要約

StringScanner は文字列スキャナクラスです。簡単に高速なスキャナを記述できます。



require '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 オブジェクトはスキャンする文字列と「スキャンポインタ」のセットです。スキャンポインタとはスキャンしおわったところを示すインデックスのことです。オブジェクト作成直後にはスキャンポインタは文字列先頭にあり、その地点でのみマッチを試します。マッチしたらその後ろにポインタを進めます。



require 'strscan'

## 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#scan_untilなどを使ってください。

例: scan, scan_until の動作の違い

require 'strscan'

def case1
  s = StringScanner.new('test string')
  p s.scan(/t/)       #=> "t"
  p s.scan(/\w+/)     #=> "est"
  p s.scan(/string/)  #=> nil
  p s.scan(/\s+/)     #=> " "
  p s.scan(/string/)  #=> "string"
end

def case2
  s = StringScanner.new('test string')
  p s.scan_until(/t/)       #=> "t"
  p s.scan_until(/\w+/)     #=> "est"
  p s.scan_until(/string/)  #=> " string"
  p s.scan_until(/\s+/)     #=> nil
  p s.scan_until(/string/)  #=> nil
end

p "case1"
case1
p "case2"
case2

スキャンポインタの位置は文字単位でなくバイト単位となります。

例:

# 次の行以降の内容を EUC-JP として保存して試してください
# vim:set fileencoding=euc-jp:
require 'strscan'
s = StringScanner.new("るびい") # 文字コードはEUC-JPとします
p s.exist?(/び/) #=> 4

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

目次

特異メソッド
インスタンスメソッド
定数

特異メソッド

must_C_version -> self[permalink][rdoc][edit]

このメソッドは後方互換性のために定義されています。

new(str, dup = false) -> StringScanner[permalink][rdoc][edit]

新しい StringScanner オブジェクトを生成します。

[PARAM] str:
スキャン対象の文字列を指定します。
[PARAM] dup:
dup は単に無視します。引数の文字列は複製も freeze もされず、そのまま使います。


require '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+/)   #=> " "

インスタンスメソッド

self << str -> self[permalink][rdoc][edit]
concat(str) -> self

操作対象の文字列に対し str を破壊的に連結します。マッチ記録は変更されません。

selfを返します。

[PARAM] str:
操作対象の文字列に対し str を破壊的に連結します。


require 'strscan'

s = StringScanner.new('test') # => #<StringScanner 0/4 @ "test">
s.scan(/\w(\w*)/)             # => "test"
s[0]                          # => "test"
s[1]                          # => "est"
s << ' string'                # => #<StringScanner 4/11 "test" @ " stri...">
s[0]                          # => "test"
s[1]                          # => "est"
s.scan(/\s+/)                 # => " "
s.scan(/\w+/)                 # => "string"

この操作は StringScanner.new に渡した文字列にも影響することがあります。



require 'strscan'

str = 'test'
s = StringScanner.new(str) # => #<StringScanner 0/4 @ "test">
s << ' string'             # => #<StringScanner 0/11 @ "test ...">
str                        # => "test string"
self[nth] -> String | nil[permalink][rdoc][edit]

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

[PARAM] nth:
前回マッチした正規表現の nth 番目のかっこに対応する部分文字列を返します。


require 'strscan'

s = StringScanner.new('test string')
s.scan(/\w(\w)(\w*)/) # => "test"
s[0]                  # => "test"
s[1]                  # => "e"
s[2]                  # => "st"
s.scan(/\w+/)         # => nil
s[0]                  # => nil
s[1]                  # => nil
s[2]                  # => nil
s.scan(/\s+/)         # => " "
s[0]                  # => " "
s[1]                  # => nil
s[2]                  # => nil
s.scan(/\w(\w)(\w*)/) # => "string"
s[0]                  # => "string"
s[1]                  # => "t"
s[2]                  # => "ring"
beginning_of_line? -> bool[permalink][rdoc][edit]
bol? -> bool

スキャンポインタが行頭を指しているなら true を、行頭以外を指しているなら false を返します。

行頭の定義は、文字列先頭かまたは \n の直後を指していることです。文字列末尾は必ずしも行頭ではありません。



require 'strscan'

s = StringScanner.new("test\nstring")
s.bol?        # => true
s.scan(/\w+/)
s.bol?        # => false
s.scan(/\n/)
s.bol?        # => true
s.scan(/\w+/)
s.bol?        # => false
charpos -> Integer[permalink][rdoc][edit]

現在のスキャンポインタのインデックスを文字単位で返します。



require 'strscan'

s = StringScanner.new("abcädeföghi")
s.charpos           # => 0
s.scan_until(/ä/)   # => "abcä"
s.pos               # => 5
s.charpos           # => 4

[SEE_ALSO] StringScanner#pos

check(regexp) -> String | nil[permalink][rdoc][edit]

現在位置から regexp とのマッチを試みます。マッチに成功したらマッチした部分文字列を返します。マッチに失敗したら nil を返します。

このメソッドはマッチが成功してもスキャンポインタを進めません。

[PARAM] regexp:
マッチに用いる正規表現を指定します。


require 'strscan'

s = StringScanner.new('test string')
s.check(/\w+/) # => "test"
s.pos          # => 0
s.matched      # => "test"
s.check(/\s+/) # => nil
s.matched      # => nil
check_until(regexp) -> String | nil[permalink][rdoc][edit]

regexp が一致するまで文字列をスキャンします。マッチに成功したらスキャン開始位置からマッチ部分の末尾までの部分文字列を返します。マッチに失敗したら nil を返します。

このメソッドはマッチが成功してもスキャンポインタを進めません。

[PARAM] regexp:
マッチに用いる正規表現を指定します。


require 'strscan'

s = StringScanner.new('test string')
s.check_until(/str/) # => "test str"
s.matched            # => "str"
s.pos                # => 0
s.pre_match          # => "test "
terminate -> self[permalink][rdoc][edit]
clear -> self

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

[RETURN]
self を返します。

pos = self.string.size と同じ動作です。



require 'strscan'

s = StringScanner.new('test string')
s.scan(/\w+/) # => "test"
s.matched     # => "test"
s.pos         # => 4
s[0]          # => "test"
s.terminate
s.matched     # => nil
s[0]          # => nil
s.pos         # => 11

StringScanner#clear は将来のバージョンで削除される予定です。代わりに StringScanner#terminate を使ってください。

eos? -> bool[permalink][rdoc][edit]
empty? -> bool

スキャンポインタが文字列の末尾を指しているなら true を、末尾以外を指しているなら false を返します。



require 'strscan'

s = StringScanner.new('test string')
s.eos?        # => false
s.scan(/\w+/)
s.scan(/\s+/)
s.scan(/\w+/)
s.eos?        # => true

StringScanner#empty? は将来のバージョンで削除される予定です。代わりに StringScanner#eos? を使ってください。

exist?(regexp) -> Integer | nil[permalink][rdoc][edit]

スキャンポインタの位置から,次にマッチする文字列の末尾までの長さを返します。

マッチに失敗したら nil を返します。

このメソッドはマッチが成功してもスキャンポインタを進めません。

[PARAM] regexp:
マッチに用いる正規表現を指定します。


require 'strscan'

s = StringScanner.new('test string')
s.exist?(/s/) # => 3
s.exist?(//)  # => 0
s.scan(/\w+/) # => "test"
s.exist?(/s/) # => 2
s.exist?(/e/) # => nil
get_byte -> String | nil[permalink][rdoc][edit]
getbyte -> String | nil

1 バイトスキャンして文字列で返します。スキャンポインタをその後ろに進めます。スキャンポインタが文字列の末尾を指すなら nil を返します。

StringScanner#getbyte は将来のバージョンで削除される予定です。代わりに StringScanner#get_byte を使ってください。



require 'strscan'

utf8 = "\u{308B 3073 3044}"
s = StringScanner.new(utf8.encode("EUC-JP"))
p s.get_byte       #=> "\xA4"
p s.get_byte       #=> "\xEB"
p s.get_byte       #=> "\xA4"
p s.get_byte       #=> "\xD3"
p s.get_byte       #=> "\xA4"
p s.get_byte       #=> "\xA4"
p s.get_byte       #=> nil   
getch -> String | nil[permalink][rdoc][edit]

一文字スキャンして文字列で返します。スキャンポインタをその後ろに進めます。スキャンポインタが文字列の末尾を指すならnilを返します。

一文字の定義は、与えた文字列のエンコードに依存します。



require 'strscan'

utf8 = "\u{308B 3073 3044}"
s = StringScanner.new(utf8.encode("UTF-8")) 
p s.getch                         # => "る"
p s.getch                         # => "び"
p s.getch                         # => "い"
p s.getch                         # => nil
inspect -> String[permalink][rdoc][edit]

StringScannerオブジェクトを表す文字列を返します。

文字列にはクラス名の他、以下の情報が含まれます。

  • スキャナポインタの現在位置。
  • スキャン対象の文字列の長さ。
  • スキャンポインタの前後にある文字。上記実行例の @ がスキャンポインタを表します。


require 'strscan'

s = StringScanner.new('test string')
s.inspect                            # => "#<StringScanner 0/11 @ \"test ...\">"
s.scan(/\w+/)                        # => "test"
s.inspect                            # => "#<StringScanner 4/11 \"test\" @ \" stri...\">"
s.scan(/\s+/)                        # => " "
s.inspect                            # => "#<StringScanner 5/11 \"test \" @ \"strin...\">"
s.scan(/\w+/)                        # => "string"
s.inspect                            # => "#<StringScanner fin>"
match?(regexp) -> Integer | nil[permalink][rdoc][edit]

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

マッチしたサイズは文字単位でなくバイト単位となります。


require 'strscan'
def case1(encode)
  utf8 = "\u{308B 3073 3044}"
  s = StringScanner.new(utf8.encode(encode))
  s.match?(/#{"\u{308B}".encode(encode)}/)
end

p case1("EUC-JP")     #=> 2
[PARAM] regexp:
マッチに用いる正規表現を指定します。


require 'strscan'

s = StringScanner.new('test string')
p s.match?(/\w+/)   #=> 4
p s.match?(/\w+/)   #=> 4
p s.match?(/\s+/)   #=> nil
matched -> String | nil[permalink][rdoc][edit]

前回マッチした部分文字列を返します。前回のマッチに失敗していると nil を返します。



require 'strscan'

s = StringScanner.new('test string')
s.matched     # => nil
s.scan(/\w+/) # => "test"
s.matched     # => "test"
s.scan(/\w+/) # => nil
s.matched     # => nil
s.scan(/\s+/) # => " "
s.matched     # => " "
matched? -> bool[permalink][rdoc][edit]

前回のマッチが成功していたら true を、失敗していたら false を返します。



require 'strscan'

s = StringScanner.new('test string')
s.matched?    # => false
s.scan(/\w+/) # => "test"
s.matched?    # => true
s.scan(/\w+/) # => nil
s.matched?    # => false
s.scan(/\s+/) # => " "
s.matched?    # => true
matched_size -> Integer | nil[permalink][rdoc][edit]

前回マッチした部分文字列の長さを返します。前回マッチに失敗していたら nil を返します。

マッチしたサイズは文字単位でなくバイト単位となります。


require 'strscan'

def run(encode)
  utf8 = "\u{308B 3073 3044}" # るびい
  s = StringScanner.new(utf8.encode(encode))
  s.scan(/#{"\u{308B}".encode(encode)}/)
  s.matched_size
end

p run("UTF-8")     #=> 3
p run("EUC-JP")    #=> 2
p run("Shift_Jis") #=> 2



require 'strscan'

s = StringScanner.new('test string')
s.matched_size # => nil
s.scan(/\w+/)  # => "test"
s.matched_size # => 4
s.scan(/\w+/)  # => nil
s.matched_size # => nil
matchedsize -> Integer | nil[permalink][rdoc][edit]

StringScanner#matched_size と同じです。

このメソッドは は将来のバージョンで削除される予定です。代わりに StringScanner#matched_size を使ってください。

[SEE_ALSO] StringScanner#matched_size

peek(bytes) -> String[permalink][rdoc][edit]
peep(bytes) -> String

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



require 'strscan'
s = StringScanner.new('test string')
s.peek(4)   # => "test"

また、このメソッドを実行してもスキャンポインタは移動しません。

StringScanner#peep は将来のバージョンでは削除される予定です。代わりに StringScanner#peek を使ってください。

[PARAM] bytes:
0 以上の整数を指定します。ただし、スキャン対象の文字列の長さを超える分は無視されます。 bytes が 0 のとき、またはスキャンポインタが文字列の末尾を指しているときは空文字列 ("") を返します。
[EXCEPTION] ArgumentError:
bytes に負数を与えると発生します。


require 'strscan'

s = StringScanner.new('test string')
p s.peek(4)     # => "test"
p s.peek(20)    # => "test string"
p s.peek(0)     # => ""
begin
  s.peek(-1)
rescue ArgumentError => err
  puts err # negative string size (or size too big)
end
p s.scan(/\w+/) # => "test"
p s.scan(/\s+/) # => " "
p s.scan(/\w+/) # => "string"
p s.peek(4)     # => ""

# このメソッドを実行してもスキャンポインタは移動しません。

s = StringScanner.new('test string')
p s.peek(4)     # => "test"
p s.peek(4)     # => "test"
p s.scan(/\w+/) # => "test"
p s.peek(4)     # => " str"
p s.peek(4)     # => " str"
pointer -> Integer[permalink][rdoc][edit]
pos -> Integer

現在のスキャンポインタのインデックスを返します。



require 'strscan'

s = StringScanner.new('test string')
s.pos         # => 0
s.scan(/\w+/) # => "test"
s.pos         # => 4
s.scan(/\w+/) # => nil
s.pos         # => 4
s.scan(/\s+/) # => " "
s.pos         # => 5

[SEE_ALSO] StringScanner#charpos

pointer=(n)[permalink][rdoc][edit]
pos=(n)

スキャンポインタのインデックスを n にセットします。

[PARAM] n:
整数で、バイト単位で指定します。負数を指定すると文字列の末尾からのオフセットとして扱います。
[EXCEPTION] RangeError:
マッチ対象の文字列の長さを超える値を指定すると発生します。
[RETURN]
n を返します。


require 'strscan'

s = StringScanner.new('test string')
p s.scan(/\w+/) # => "test"
p s.pos = 1     # => 1
p s.scan(/\w+/) # => "est"
p s.pos = 7     # => 7
p s.scan(/\w+/) # => "ring"

begin
  s.pos = 20
rescue RangeError => err
  puts err #=> index out of range
end
p s.pos = -4    # => -4
p s.scan(/\w+/) # => "ring"
post_match -> String | nil[permalink][rdoc][edit]

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



require 'strscan'

s = StringScanner.new('test string')
s.post_match  # => nil
s.scan(/\w+/) # => "test"
s.post_match  # => " string"
s.scan(/\w+/) # => nil
s.post_match  # => nil
s.scan(/\s+/) # => " "
s.post_match  # => "string"
s.scan(/\w+/) # => "string"
s.post_match  # => ""
s.scan(/\w+/) # => nil
s.post_match  # => nil
pre_match -> String | nil[permalink][rdoc][edit]

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



require 'strscan'

s = StringScanner.new('test string')
s.pre_match   # => nil
s.scan(/\w+/) # => "test"
s.pre_match   # => ""
s.scan(/\w+/) # => nil
s.pre_match   # => nil
s.scan(/\s+/) # => " "
s.pre_match   # => "test"
s.scan(/\w+/) # => "string"
s.pre_match   # => "test "
s.scan(/\w+/) # => nil
s.pre_match   # => nil
reset -> self[permalink][rdoc][edit]

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

pos = 0と同じ動作です。

[RETURN]
self を返します。


require 'strscan'

s = StringScanner.new('test string')
s.scan(/\w+/) # => "test"
s.matched     # => "test"
s.pos         # => 4
s[0]          # => "test"
s.reset
s.matched     # => nil
s[0]          # => nil
s.pos         # => 0
rest -> String[permalink][rdoc][edit]

文字列の残り (rest) を返します。具体的には、スキャンポインタが指す位置からの文字列を返します。

スキャンポインタが文字列の末尾を指していたら空文字列 ("") を返します。



require 'strscan'

s = StringScanner.new('test string')
s.rest         # => "test string"
s.scan(/\w+/)  # => "test"
s.rest         # => " string"
s.scan(/\s+/)  # => " "
s.rest         # => "string"
s.scan(/\w+/)  # => "string"
s.rest         # => ""
rest? -> bool[permalink][rdoc][edit]

文字列が残っているならば trueを、残っていないならば false を返します。

StringScanner#eos? と逆の結果を返します。

StringScanner#rest? は将来のバージョンで削除される予定です。代わりに StringScanner#eos? を使ってください。



require 'strscan'

s = StringScanner.new('test string')
p s.eos?        # => false
p s.rest?       # => true
s.scan(/\w+/)
s.scan(/\s+/)
s.scan(/\w+/)
p s.eos?        # => true
p s.rest?       # => false
rest_size -> Integer[permalink][rdoc][edit]
restsize -> Integer

文字列の残りの長さを返します。 stringscanner.rest.size と同じです。

StringScanner#restsize は将来のバージョンで削除される予定です。代わりにStringScanner#rest_size を使ってください。



require 'strscan'

s = StringScanner.new('test string')
p s.rest_size # => 11
p s.rest.size # => 11
scan(regexp) -> String | nil[permalink][rdoc][edit]

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

[PARAM] regexp:
マッチに用いる正規表現を指定します。


require 'strscan'

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
scan_full(regexp, s, f) -> object[permalink][rdoc][edit]

スキャンポインタの位置から regexp と文字列のマッチを試します。

マッチに成功すると、s と f の値によって以下のように動作します。

  • s が true ならばスキャンポインタを進めます。
  • s が false ならばスキャンポインタを進めません。
  • f が true ならばマッチした部分文字列を返します。
  • f が false ならばマッチした部分文字列の長さを返します。

マッチに失敗すると s や f に関係なく nil を返します。

このメソッドは s と f の組み合わせにより、他のメソッドと同等の動作になります。

[PARAM] regexp:
マッチに用いる正規表現を指定します。
[PARAM] s:
true ならばスキャンポインタを進めます。 false ならばスキャンポインタを進めません。
[PARAM] f:
true ならばマッチした部分文字列を返します。 false ならばマッチした部分文字列の長さを返します。


require 'strscan'

s = StringScanner.new('test string')
p s.scan_full(/\w+/, true, true)     #=> "test"
p s.scan_full(/\s+/, false, true)    #=> " "
p s.scan_full(/\s+/, true, false)    #=> 1
p s.scan_full(/\w+/, false, false)   #=> 6
p s.scan_full(/\w+/, true, true)     #=> "string"

[SEE_ALSO] StringScanner#scan StringScanner#skip StringScanner#check StringScanner#match?

scan_until(regexp) -> String | nil[permalink][rdoc][edit]

regexp で指定された正規表現とマッチするまで文字列をスキャンします。マッチに成功したらスキャンポインタを進めて、スキャン開始位置からマッチ部分の末尾までの部分文字列を返します。マッチに失敗したら nil を返します。

[PARAM] regexp:
マッチに用いる正規表現を指定します。


require 'strscan'

s = StringScanner.new('test string')
s.scan_until(/str/) # => "test str"
s.matched           # => "str"
s.pos               # => 8
s.pre_match         # => "test "
search_full(regexp, s, f) -> object[permalink][rdoc][edit]

regexp で指定された正規表現とマッチするまで文字列をスキャンします。

マッチに成功すると、s と f の値によって以下のように動作します。

  • s が true ならばスキャンポインタを進めます。
  • s が false ならばスキャンポインタを進めません。
  • f が true ならばスキャン開始位置からマッチした部分の末尾までの部分文字列を返します。
  • f が false ならばスキャン開始位置からマッチした部分の末尾までの部分文字列の長さを返します。

マッチに失敗すると s や f に関係なく nil を返します。

このメソッドは s と f の組み合わせにより、他のメソッドと同等の動作になります。

[PARAM] regexp:
マッチに用いる正規表現を指定します。
[PARAM] s:
true ならばスキャンポインタを進めます。 false ならばスキャンポインタを進めません。
[PARAM] f:
true ならばマッチした部分文字列を返します。 false ならばマッチした部分文字列の長さを返します。


require 'strscan'

s = StringScanner.new('test string')   
p s.search_full(/t/, true, true)       #=> "t"
p s.search_full(/str/, false, true)    #=> "est str"
p s.search_full(/string/, true, true)  #=> "est string"

[SEE_ALSO] StringScanner#scan_until StringScanner#skip_until StringScanner#check_until StringScanner#exist?

skip(regexp) -> Integer | nil[permalink][rdoc][edit]

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

[PARAM] regexp:
マッチに使用する正規表現を指定します。


require 'strscan'

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
skip_until(regexp) -> Integer | nil[permalink][rdoc][edit]

regexp が一致するまで文字列をスキャンします。マッチに成功したらスキャンポインタを進めて、スキャン開始位置からマッチ部分の末尾までの部分文字列の長さを返します。マッチに失敗したら nil を返します。

[PARAM] regexp:
マッチに使用する正規表現を指定します。


require 'strscan'

s = StringScanner.new('test string')
s.scan_until(/str/) # => 8
s.matched           # => "str"
s.pos               # => 8
s.pre_match         # => "test "
string -> String[permalink][rdoc][edit]

スキャン対象にしている文字列を返します。



require 'strscan'

s = StringScanner.new('test string')
s.string # => "test string"

返り値は freeze されていません。



require 'strscan'

s = StringScanner.new('test string')
s.string.frozen? # => false

なお、このメソッドは StringScanner.new に渡した文字列をそのまま返しますが、この仕様が将来に渡って保証されるわけではありません。この仕様に依存したコードを書かないようにしましょう。



require 'strscan'

str = 'test string'
s = StringScanner.new(str)
s.string == str    # => true
s.string.eql?(str) # => true (将来は false になる可能性がある)

また、返り値の文字列に対して破壊的な変更もできますが、この操作がスキャン対象の文字列を変更することも保証されません。この仕様に依存したコードを書かないでください。



require 'strscan'

str = 'test string'
s = StringScanner.new(str)
s.string.replace("0123")
s.scan(/\w+/)     # => "0123" (将来は "test" が返る可能性あり)
str               # => "0123" (将来は "test string" が返る可能性あり)
string=(str)[permalink][rdoc][edit]

スキャン対象の文字列を str に変更して、マッチ記録を捨てます。

[PARAM] str:
スキャン対象の文字列を str に変更して、マッチ記録を捨てます。
[RETURN]
str を返します。


require 'strscan'

str = '0123'
s = StringScanner.new('test string')
s.string = str     # => "0123"
s.scan(/\w+/)      # => "0123"
unscan -> self[permalink][rdoc][edit]

スキャンポインタを前回のマッチの前の位置に戻します。



require 'strscan'

s = StringScanner.new('test string')
s.scan(/\w+/) # => "test"
s.unscan
s.scan(/\w+/) # => "test"
[RETURN]
selfを返します。

このメソッドでポインタを戻せるのは 1 回分だけです。 2 回分以上戻そうとしたときは例外 StringScanner::Error が発生します。また、まだマッチを一度も行っていないときや、前回のマッチが失敗していたときも例外 StringScanner::Error が発生します。

[EXCEPTION] StringScanner::Error:
2 回分以上戻そうとした時や、まだマッチを一度も行っていない時、前回のマッチが失敗していた時に発生します。


require 'strscan'

s = StringScanner.new('test string')
begin
  # マッチを一度も行っていないので、例外が発生する。
  s.unscan
rescue StringScanner::Error => err
  puts err
  # 出力例
  #=> unscan failed: previous match had failed
end
p s.scan(/\w+/) # => "test"
s.unscan
begin
  # 二回以上戻そうとしたので、例外が発生する。
  s.unscan
rescue StringScanner::Error => err
  puts err
  # 出力例
  #=> unscan failed: previous match had failed
end
p s.scan(/\w+/) # => "test"
p s.scan(/\w+/) # => nil
begin
  # 前回のマッチが失敗しているので、例外が発生する。
  s.unscan
rescue => err
  puts err
  # 出力例
  #=> unscan failed: previous match had failed
end

定数

Id -> String[permalink][rdoc][edit]

StringScanner クラスの詳しいバージョンを文字列で返します。この文字列は Object#freeze されています。

Version -> String[permalink][rdoc][edit]

StringScanner クラスのバージョンを文字列で返します。この文字列は Object#freeze されています。



require 'strscan'

StringScanner::Version           # => "0.7.0"
StringScanner::Version.frozen?   # => true