class

StringScanner

Inherits Reference / Object

StringScanner provides for lexical scanning operations on a String.

NOTE: To use StringScanner, you must explicitly import it with require "string_scanner"

Example

require "string_scanner"

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

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

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

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

Scanning a string means remembering the position of a scan offset, which is just an index. Scanning moves the offset forward, and matches are sought after the offset; usually immediately after it.

Method Categories

Methods that advance the scan offset:

  • #scan
  • #scan_until
  • #skip
  • #skip_until

Methods that look ahead or behind:

  • #peek
  • #peek_behind
  • #check
  • #check_until
  • #rest
  • #current_char, #current_char?
  • #previous_char, #previous_char?
  • #current_byte, #current_byte?
  • #previous_byte, #previous_byte?

Methods that deal with the position of the offset:

  • #offset
  • #offset=
  • #rewind
  • #eos?
  • #reset
  • #terminate

Methods that deal with the last match:

  • #[]
  • #[]?
  • #matched?

Miscellaneous methods:

  • #inspect
  • #string

Constructors

new(str : String)
Source

Instance methods

[](n) : String

Returns the n-th subgroup in the most recent match.

Raises an exception if there was no last match or if there is no subgroup.

require "string_scanner"

s = StringScanner.new("Fri Dec 12 1975 14:39")
regex = /(?<wday>\w+) (?<month>\w+) (?<day>\d+)/
s.scan(regex) # => "Fri Dec 12"
s[0]          # => "Fri Dec 12"
s[1]          # => "Fri"
s[2]          # => "Dec"
s[3]          # => "12"
s["wday"]     # => "Fri"
s["month"]    # => "Dec"
s["day"]      # => "12"
Source
[]?(n) : String | Nil

Returns the nilable n-th subgroup in the most recent match.

Returns nil if there was no last match or if there is no subgroup.

require "string_scanner"

s = StringScanner.new("Fri Dec 12 1975 14:39")
regex = /(?<wday>\w+) (?<month>\w+) (?<day>\d+)/
s.scan(regex)  # => "Fri Dec 12"
s[0]?          # => "Fri Dec 12"
s[1]?          # => "Fri"
s[2]?          # => "Dec"
s[3]?          # => "12"
s[4]?          # => nil
s["wday"]?     # => "Fri"
s["month"]?    # => "Dec"
s["day"]?      # => "12"
s["year"]?     # => nil
s.scan(/more/) # => nil
s[0]?          # => nil
Source
beginning_of_line?

Returns true if the stream is at the beginning of a line and not at EOS.

Source
byte_offset

The byte offset of the scan head. This is distinct from #offset in that it counts raw bytes instead of characters.

Source
check(pattern : String) : String | Nil

Returns the value that #scan would return, without advancing the scan offset. The last match is still saved, however.

require "string_scanner"

s = StringScanner.new("this is a string")
s.offset = 5
s.check(/\w+/) # => "is"
s.check(/\w+/) # => "is"
Source
check(pattern : Char) : String | Nil

Returns the value that #scan would return, without advancing the scan offset. The last match is still saved, however.

require "string_scanner"

s = StringScanner.new("this is a string")
s.offset = 5
s.check(/\w+/) # => "is"
s.check(/\w+/) # => "is"
Source
check(len : Int) : String | Nil

Returns the value that #scan would return, without advancing the scan offset. The last match is still saved, however.

require "string_scanner"

s = StringScanner.new("this is a string")
s.offset = 5
s.check(/\w+/) # => "is"
s.check(/\w+/) # => "is"
Source
check(pattern : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : String | Nil

Returns the value that #scan would return, without advancing the scan offset. The last match is still saved, however.

require "string_scanner"

s = StringScanner.new("this is a string")
s.offset = 5
s.check(/\w+/) # => "is"
s.check(/\w+/) # => "is"
Source
check_until(pattern : String) : String | Nil

Returns the value that #scan_until would return, without advancing the scan offset. The last match is still saved, however.

require "string_scanner"

s = StringScanner.new("test string")
s.check_until(/tr/) # => "test str"
s.check_until(/g/)  # => "test string"
Source
check_until(pattern : Char) : String | Nil

Returns the value that #scan_until would return, without advancing the scan offset. The last match is still saved, however.

require "string_scanner"

s = StringScanner.new("test string")
s.check_until(/tr/) # => "test str"
s.check_until(/g/)  # => "test string"
Source
check_until(pattern : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : String | Nil

Returns the value that #scan_until would return, without advancing the scan offset. The last match is still saved, however.

require "string_scanner"

s = StringScanner.new("test string")
s.check_until(/tr/) # => "test str"
s.check_until(/g/)  # => "test string"
Source
current_byte

Returns the current byte at the scan head, and errors if at the end. Does not move the scan head. Does no multi-byte character checking, and may return part of a multi-byte character. See #current_char.

Source
current_byte?

Returns the current byte at the scan head, or nil if at the end. Does no multi-byte character checking, and may return part of a multi-byte character. See #current_char?.

Source
current_char

Returns the character at the scan head, and errors if at the end. Does not move the scan head. This will properly decode the next character from the string, and may return a multi-byte character.

Source
current_char?

Returns the character at the scan head, or nil if at the end. Does not move the scan head. This will properly decode the next character from the string, and may return a multi-byte character.

Source
eos?

Returns true if the scan offset is at the end of the string.

require "string_scanner"

s = StringScanner.new("this is a string")
s.eos?                # => false
s.scan(/(\w+\s?){4}/) # => "this is a string"
s.eos?                # => true
Source
inspect(io : IO) : Nil

Writes a representation of the scanner.

Includes the current position of the offset, the total size of the string, and five characters near the current position.

Source
matched?

Returns true if the last #scan resulted in a match

Source
offset

Returns the current position of the scan offset.

Source
offset=(position : Int)

Sets the position of the scan offset.

NOTE: Moving the scan head to a non-zero index with this method can cause performance issues in multibyte strings. For a more performant way to move the head, see #skip(Int) or #rewind.

Source
peek(len) : String

Extracts a string by looking ahead len characters, without advancing the scan offset. The return value has at most len characters, but may have fewer if the scan head is close to the end of the string.

Source
peek_behind(len) : String

Extracts a string by looking behind len characters, without moving the scan offset. The return value has at most len characters, but may have fewer if the scan head is close to the beginning of the string.

Source
previous_byte

Returns the byte before the scan head, and errors if at the beginning. Does not move the scan head. This performs no multi-byte checking and may return part of a multi-byte character. See #previous_char

Source
previous_byte?

Returns the byte before the scan head, or nil if at the beginning. Does not move the scan head. This performs no multi-byte checking and may return part of a multi-byte character. See #previous_char?.

Source
previous_char

Returns the character before the scan head, and errors if at the beginning. Does not move the scan head. This will properly decode the previous character from the string, and may return a multi-byte character.

Source
previous_char?

Returns the character before the scan head, or nil if at the beginning. Does not move the scan head. This will properly decode the previous character from the string, and may return a multi-byte character.

Source
reset

Resets the scan offset to the beginning and clears the last match.

Source
rest

Returns the remainder of the string after the scan offset.

require "string_scanner"

s = StringScanner.new("this is a string")
s.scan(/(\w+\s?){2}/) # => "this is "
s.rest                # => "a string"
Source
rewind(len : Int) : Nil

Rewinds the scan head by len characters.

Raises IndexError if this would go off the beginning of the stream.

Source
scan(pattern : String) : String | Nil

Tries to match with pattern at the current position. If there's a match, the scanner advances the scan offset, the last match is saved, and it returns the matched string. Otherwise, the scanner returns nil.

require "string_scanner"

s = StringScanner.new("test string")
s.scan(/\w+/)  # => "test"
s.scan(/\w+/)  # => nil
s.scan(/\s\w/) # => " s"
s.scan('t')    # => "t"
s.scan("ring") # => "ring"
s.scan(/.*/)   # => ""
Source
scan(pattern : Char) : String | Nil

Tries to match with pattern at the current position. If there's a match, the scanner advances the scan offset, the last match is saved, and it returns the matched string. Otherwise, the scanner returns nil.

require "string_scanner"

s = StringScanner.new("test string")
s.scan(/\w+/)  # => "test"
s.scan(/\w+/)  # => nil
s.scan(/\s\w/) # => " s"
s.scan('t')    # => "t"
s.scan("ring") # => "ring"
s.scan(/.*/)   # => ""
Source
scan(len : Int) : String | Nil

Advances the offset by len chars, and returns a string of that length.

NOTE: If there are less than the requested number of characters remaining in the string, this method will return nil and not advance the scan head. To obtain the entire rest of the input string, use #rest.

require "string_scanner"

s = StringScanner.new("あいうえお")
s.scan(3)   # => "あいう"
s.scan(100) # => nil
s.scan(2)   # => "えお"
s.scan(0)   # => ""
Source
scan(pattern : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : String | Nil

Tries to match with pattern at the current position. If there's a match, the scanner advances the scan offset, the last match is saved, and it returns the matched string. Otherwise, the scanner returns nil.

require "string_scanner"

s = StringScanner.new("test string")
s.scan(/\w+/)  # => "test"
s.scan(/\w+/)  # => nil
s.scan(/\s\w/) # => " s"
s.scan('t')    # => "t"
s.scan("ring") # => "ring"
s.scan(/.*/)   # => ""
Source
scan_until(pattern : String) : String | Nil

Scans the string until the pattern is matched. Returns the substring up to and including the end of the match, the last match is saved, and advances the scan offset. Returns nil if no match.

require "string_scanner"

s = StringScanner.new("test string")
s.scan_until(/ s/) # => "test s"
s.scan_until(/ s/) # => nil
s.scan_until('r')  # => "tr"
s.scan_until("ng") # => "ing"
Source
scan_until(pattern : Char) : String | Nil

Scans the string until the pattern is matched. Returns the substring up to and including the end of the match, the last match is saved, and advances the scan offset. Returns nil if no match.

require "string_scanner"

s = StringScanner.new("test string")
s.scan_until(/ s/) # => "test s"
s.scan_until(/ s/) # => nil
s.scan_until('r')  # => "tr"
s.scan_until("ng") # => "ing"
Source
scan_until(pattern : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : String | Nil

Scans the string until the pattern is matched. Returns the substring up to and including the end of the match, the last match is saved, and advances the scan offset. Returns nil if no match.

require "string_scanner"

s = StringScanner.new("test string")
s.scan_until(/ s/) # => "test s"
s.scan_until(/ s/) # => nil
s.scan_until('r')  # => "tr"
s.scan_until("ng") # => "ing"
Source
skip(pattern : String) : Int32 | Nil

Attempts to skip over the given pattern beginning with the scan offset.

If there's a match, the scanner advances the scan offset, the last match is saved, and it returns the size of the skipped match. Otherwise it returns nil and does not advance the offset.

This method is the same as #scan, but without returning the matched string.

Source
skip(pattern : Char) : Int32 | Nil

Attempts to skip over the given pattern beginning with the scan offset.

If there's a match, the scanner advances the scan offset, the last match is saved, and it returns the size of the skipped match. Otherwise it returns nil and does not advance the offset.

This method is the same as #scan, but without returning the matched string.

Source
skip(len : Int) : Int32 | Nil

Advances the offset by len chars.

Prefer this to scanner.offset += len, since that can cause a full scan of the string in the case of multibyte characters.

NOTE: If there are less than the requested number of characters remaining in the string, this method will return nil and not advance the scan head. To move the scan head to the very end, use #terminate.

Source
skip(pattern : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : Int32 | Nil

Attempts to skip over the given pattern beginning with the scan offset.

If there's a match, the scanner advances the scan offset, the last match is saved, and it returns the size of the skipped match. Otherwise it returns nil and does not advance the offset.

This method is the same as #scan, but without returning the matched string.

Source
skip_until(pattern : String) : Int32 | Nil

Attempts to skip until the given pattern is found after the scan offset. In other words, the pattern is not anchored to the current scan offset.

If there's a match, the scanner advances the scan offset, the last match is saved, and it returns the size of the skip. Otherwise it returns nil and does not advance the offset.

This method is the same as #scan_until, but without returning the matched string.

Source
skip_until(pattern : Char) : Int32 | Nil

Attempts to skip until the given pattern is found after the scan offset. In other words, the pattern is not anchored to the current scan offset.

If there's a match, the scanner advances the scan offset, the last match is saved, and it returns the size of the skip. Otherwise it returns nil and does not advance the offset.

This method is the same as #scan_until, but without returning the matched string.

Source
skip_until(pattern : Regex, *, options : Regex::MatchOptions = Regex::MatchOptions::None) : Int32 | Nil

Attempts to skip until the given pattern is found after the scan offset. In other words, the pattern is not anchored to the current scan offset.

If there's a match, the scanner advances the scan offset, the last match is saved, and it returns the size of the skip. Otherwise it returns nil and does not advance the offset.

This method is the same as #scan_until, but without returning the matched string.

Source
string

Returns the string being scanned.

Source
terminate

Moves the scan offset to the end of the string and clears the last match.

Source