Ruby 4.1 リファレンスマニュアル

class StringScanner

[edit]

要約

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

require 'strscan'

s = StringScanner.new('This is an example string')
p 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"
p 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"
p 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')
p 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">
p s.scan(/\w(\w*)/)           # => "test"
p s[0]                        # => "test"
p s[1]                        # => "est"
p s << ' string'              # => #<StringScanner 4/11 "test" @ " stri...">
p s[0]                        # => "test"
p s[1]                        # => "est"
p s.scan(/\s+/)               # => " "
p s.scan(/\w+/)               # => "string"

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

require 'strscan'

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

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

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

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

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

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

require 'strscan'

s = StringScanner.new("test\nstring")
p s.bol?      # => true
s.scan(/\w+/)
p s.bol?      # => false
s.scan(/\n/)
p s.bol?      # => true
s.scan(/\w+/)
p s.bol?      # => false
captures -> [String | nil] | nilRuby 2.5.0 から[permalink][rdoc][edit]

直前のマッチが成功していれば、キャプチャした部分文字列(インデックス 1 以降)を格納した配列を返します。マッチが失敗していれば nil を返します。

マッチに参加しなかったグループに対応する要素は nil になります。

require 'strscan'

s = StringScanner.new('Fri Dec 12 1975 14:39')
p s.captures                       # => nil
p s.scan(/(\w+) (\w+) (\d+) /)     # => "Fri Dec 12 "
p s.captures                       # => ["Fri", "Dec", "12"]
p s.scan(/(\d+)/)                  # => "1975"
p s.captures                       # => ["1975"]

[SEE_ALSO] StringScanner#[]

charpos -> IntegerRuby 2.0.0 から[permalink][rdoc][edit]

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

require 'strscan'

s = StringScanner.new("abcädeföghi")
p s.charpos         # => 0
p s.scan_until(/ä/) # => "abcä"
p s.pos             # => 5
p 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')
p s.check(/\w+/) # => "test"
p s.pos        # => 0
p s.matched    # => "test"
p s.check(/\s+/) # => nil
p s.matched    # => nil
check_until(regexp) -> String | nil[permalink][rdoc][edit]

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

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

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

s = StringScanner.new('test string')
p s.check_until(/str/) # => "test str"
p s.matched          # => "str"
p s.pos              # => 0
p s.pre_match        # => "test "
eos? -> bool[permalink][rdoc][edit]

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

require 'strscan'

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

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

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

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

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

s = StringScanner.new('test string')
p s.exist?(/s/) # => 3
p s.exist?(//)  # => 0
p s.scan(/\w+/) # => "test"
p s.exist?(/s/) # => 2
p s.exist?(/e/) # => nil
fixed_anchor? -> boolRuby 2.7.0 から[permalink][rdoc][edit]

self が fixed anchor モードで生成されていれば true を、そうでなければ false を返します。

fixed anchor モードは StringScanner.newfixed_anchor: true を指定すると有効になります。このモードでは、正規表現中の \A は現在のスキャンポインタの位置ではなく元の文字列の先頭にマッチするようになり、^ はスキャンポインタの位置に関係なく通常の行頭にマッチするようになります。

require 'strscan'

s1 = StringScanner.new('test')
p s1.fixed_anchor?                        # => false

s2 = StringScanner.new('test', fixed_anchor: true)
p s2.fixed_anchor?                        # => true
例: \A の挙動の違い
require 'strscan'

s1 = StringScanner.new("ab\ncd")
s1.scan(/a/)
p s1.scan(/\Ab/)                          # => "b"

s2 = StringScanner.new("ab\ncd", fixed_anchor: true)
s2.scan(/a/)
p s2.scan(/\Ab/)                          # => nil
例: ^ の挙動の違い
require 'strscan'

s1 = StringScanner.new("ab\ncd")
s1.scan(/a/)
p s1.scan(/^b/)                           # => "b"
s1.scan(/\n/)
p s1.scan(/^c/)                           # => "c"

s2 = StringScanner.new("ab\ncd", fixed_anchor: true)
s2.scan(/a/)
p s2.scan(/^b/)                           # => nil
s2.scan(/b\n/)
p s2.scan(/^c/)                           # => "c"

[SEE_ALSO] StringScanner.new

get_byte -> String | nil[permalink][rdoc][edit]

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

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')
p s.inspect                          # => "#<StringScanner 0/11 @ \"test ...\">"
p s.scan(/\w+/)                      # => "test"
p s.inspect                          # => "#<StringScanner 4/11 \"test\" @ \" stri...\">"
p s.scan(/\s+/)                      # => " "
p s.inspect                          # => "#<StringScanner 5/11 \"test \" @ \"strin...\">"
p s.scan(/\w+/)                      # => "string"
p s.inspect                          # => "#<StringScanner fin>"
integer_at(specifier, base = 10) -> Integer | nilRuby 4.1 から[permalink][rdoc][edit]

specifier に対応するキャプチャの部分文字列を、String#to_i と同様の変換で整数にして返します。

specifier には 0 以上の整数、負の整数、シンボル、名前付きキャプチャの名前を表す文字列を指定できます。specifier の意味は StringScanner#[] と同じです。

以下のいずれかに該当する場合は nil を返します。

  • 直前にマッチを行っていない、または直前のマッチが失敗している場合。
  • specifier が整数で、範囲外の場合。
  • specifier が指すグループがマッチに参加していない場合。

self[specifier]&.to_i(base) とほぼ同じですが、一時的な文字列オブジェクトの生成を避けます。

[PARAM] specifier:
取得するキャプチャを指定します。整数、シンボル、または文字列で指定します。
[PARAM] base:
整数へ変換する際の基数を指定します。
[EXCEPTION] IndexError:
specifier が名前付きキャプチャに対応しないシンボルまたは文字列のときに発生します。
require 'strscan'

scanner = StringScanner.new("2024-06-15")
scanner.scan(/(\d{4})-(\d{2})-(\d{2})/)
p scanner.integer_at(1)       # => 2024
p scanner.integer_at(1, 16)   # => 8228

[SEE_ALSO] StringScanner#[], String#to_i

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')
p s.matched   # => nil
p s.scan(/\w+/) # => "test"
p s.matched   # => "test"
p s.scan(/\w+/) # => nil
p s.matched   # => nil
p s.scan(/\s+/) # => " "
p s.matched   # => " "
matched? -> bool[permalink][rdoc][edit]

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

require 'strscan'

s = StringScanner.new('test string')
p s.matched?  # => false
p s.scan(/\w+/) # => "test"
p s.matched?  # => true
p s.scan(/\w+/) # => nil
p s.matched?  # => false
p s.scan(/\s+/) # => " "
p 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')
p s.matched_size # => nil
p s.scan(/\w+/)  # => "test"
p s.matched_size # => 4
p s.scan(/\w+/)  # => nil
p s.matched_size # => nil
named_captures -> {String => String | nil}Ruby 3.2 から[permalink][rdoc][edit]

直前に使用した正規表現に含まれる名前付きキャプチャグループの名前をキー、対応する部分文字列を値とするハッシュを返します。

値は、そのグループがマッチに参加していれば対応する部分文字列に、参加していなければ nil になります。直前のマッチ全体が失敗した場合も、同様にすべての値が nil になります。直前の正規表現に名前付きキャプチャグループが無い場合は空のハッシュ {} を返します。

require 'strscan'

s = StringScanner.new('Fri Dec 12 1975 14:39')
pattern = /(?<wday>\w+) (?<month>\w+) (?<day>\d+) /
s.match?(pattern)
p s.named_captures     # => {"wday" => "Fri", "month" => "Dec", "day" => "12"}

s.match?(/(\d+)/)
p s.named_captures     # => {}
例: マッチが失敗した場合
require 'strscan'

s = StringScanner.new('nope')
pattern = /(?<wday>\w+) (?<month>\w+) (?<day>\d+) /
p s.match?(pattern)     # => nil
p s.named_captures      # => {"wday" => nil, "month" => nil, "day" => nil}

[SEE_ALSO] StringScanner#[]

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

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

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

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

[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"
peek_byte -> Integer | nilRuby 3.4 から[permalink][rdoc][edit]

スキャンポインタの位置にある 1 バイトを読み取り、その文字コードを整数で返します。スキャンポインタは進めません。

マルチバイト文字であっても常に 1 バイトだけを見ます。スキャンポインタが文字列の末尾を指しているときは nil を返します。

require 'strscan'

s = StringScanner.new('ab')
p s.peek_byte    # => 97
p s.getch        # => "a"
p s.peek_byte    # => 98
p s.getch        # => "b"
p s.peek_byte    # => nil

[SEE_ALSO] StringScanner#peek, StringScanner#getch, StringScanner#scan_byte

pointer -> Integer[permalink][rdoc][edit]
pos -> Integer

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

require 'strscan'

s = StringScanner.new('test string')
p s.pos       # => 0
p s.scan(/\w+/) # => "test"
p s.pos       # => 4
p s.scan(/\w+/) # => nil
p s.pos       # => 4
p s.scan(/\s+/) # => " "
p 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')
p s.post_match  # => nil
p s.scan(/\w+/) # => "test"
p s.post_match  # => " string"
p s.scan(/\w+/) # => nil
p s.post_match  # => nil
p s.scan(/\s+/) # => " "
p s.post_match  # => "string"
p s.scan(/\w+/) # => "string"
p s.post_match  # => ""
p s.scan(/\w+/) # => nil
p s.post_match  # => nil
pre_match -> String | nil[permalink][rdoc][edit]

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

require 'strscan'

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

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

pos = 0と同じ動作です。

[RETURN]
self を返します。
require 'strscan'

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

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

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

require 'strscan'

s = StringScanner.new('test string')
p s.rest       # => "test string"
p s.scan(/\w+/)  # => "test"
p s.rest       # => " string"
p s.scan(/\s+/)  # => " "
p s.rest       # => "string"
p s.scan(/\w+/)  # => "string"
p 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]

文字列の残りの長さを返します。 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_byte -> Integer | nilRuby 3.4 から[permalink][rdoc][edit]

1 バイトスキャンして、その文字コードを整数で返します。スキャンポインタをその後ろに進めます。

このメソッドはマルチバイト文字を意識しません。常に 1 バイトだけをスキャンします。スキャンポインタが文字列の末尾を指しているときは nil を返します。

require 'strscan'

s = StringScanner.new('ab')
p s.scan_byte    # => 97
p s.scan_byte    # => 98
p s.scan_byte    # => nil
例: マルチバイト文字を含む文字列
require 'strscan'

s = StringScanner.new("るびい")
p s.scan_byte    # => 227
p s.scan_byte    # => 130
p s.scan_byte    # => 139

[SEE_ALSO] StringScanner#getch, StringScanner#get_byte, StringScanner#peek_byte

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_integer(base: 10) -> Integer | nilRuby 3.4 から[permalink][rdoc][edit]

スキャンポインタの地点から整数をスキャンし、Integer に変換して返します。マッチしなかった場合は nil を返します。

base を省略した場合や 10 を指定した場合は /[+-]?\d+/ にマッチする部分をスキャンします。base に 16 を指定した場合は /[+-]?(0x)?[0-9a-fA-F]+/ にマッチする部分をスキャンします。

[PARAM] base:
スキャンする整数の基数を指定します。10 または 16 を指定できます。
[EXCEPTION] ArgumentError:
base に 10, 16 以外を指定すると発生します。
[EXCEPTION] Encoding::CompatibilityError:
スキャン対象の文字列が ASCII 互換でないエンコーディングのとき発生します。
require 'strscan'

s = StringScanner.new('42end')
p s.scan_integer         # => 42
p s.rest                 # => "end"

s = StringScanner.new('-3')
p s.scan_integer         # => -3

s = StringScanner.new('abc')
p s.scan_integer         # => nil
例: 16 進数
require 'strscan'

s = StringScanner.new('0x1fg')
p s.scan_integer(base: 16)   # => 31
p s.rest                     # => "g"

[SEE_ALSO] StringScanner#scan, StringScanner#scan_byte

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

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

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

s = StringScanner.new('test string')
p s.scan_until(/str/) # => "test str"
p s.matched         # => "str"
p s.pos             # => 8
p 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?

size -> Integer | nilRuby 2.5.0 から[permalink][rdoc][edit]

直前のマッチが成功していれば、そのキャプチャの数(マッチ全体を含む)を返します。マッチが失敗していれば nil を返します。

require 'strscan'

s = StringScanner.new('Fri Dec 12 1975 14:39')
p s.size                          # => nil
p s.scan(/(\w+) (\w+) (\d+) /)    # => "Fri Dec 12 "
p s.size                          # => 4

[SEE_ALSO] StringScanner#captures, StringScanner#values_at

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')
p s.scan_until(/str/) # => 8
p s.matched         # => "str"
p s.pos             # => 8
p s.pre_match       # => "test "
string -> String[permalink][rdoc][edit]

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

require 'strscan'

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

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

require 'strscan'

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

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

require 'strscan'

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

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

require 'strscan'

str = 'test string'
s = StringScanner.new(str)
s.string.replace("0123")
p s.scan(/\w+/)   # => "0123" (将来は "test" が返る可能性あり)
p 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"
p s.scan(/\w+/)    # => "0123"
terminate -> self[permalink][rdoc][edit]

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

[RETURN]
self を返します。

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

require 'strscan'

s = StringScanner.new('test string')
p s.scan(/\w+/) # => "test"
p s.matched   # => "test"
p s.pos       # => 4
p s[0]        # => "test"
s.terminate
p s.matched   # => nil
p s[0]        # => nil
p s.pos       # => 11
unscan -> self[permalink][rdoc][edit]

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

require 'strscan'

s = StringScanner.new('test string')
p s.scan(/\w+/) # => "test"
s.unscan
p 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
values_at(*specifiers) -> [String | nil] | nilRuby 2.5.0 から[permalink][rdoc][edit]

直前のマッチが成功していれば、各 specifier に対応する部分文字列を集めた配列を返します。マッチが失敗していれば nil を返します。

specifier に対応する値は StringScanner#[] と同じです。

[PARAM] specifiers:
取得したいキャプチャを指定します。整数、シンボル、文字列を指定できます。
require 'strscan'

s = StringScanner.new('Fri Dec 12 1975 14:39')
s.scan(/(\w+) (\w+) (\d+) /)
p s.values_at(0, 1, 2, 3)    # => ["Fri Dec 12 ", "Fri", "Dec", "12"]
p s.values_at(0, -1)         # => ["Fri Dec 12 ", "12"]

[SEE_ALSO] StringScanner#[]

定数

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

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

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

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

require 'strscan'

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