# <!-- rdoc-file=re.c -->
# MatchData encapsulates the result of matching a Regexp against string. It is
# returned by Regexp#match and String#match, and also stored in a global
# variable returned by Regexp.last_match.
#
# Usage:
#
#     url = 'https://docs.ruby-lang.org/en/2.5.0/MatchData.html'
#     m = url.match(/(\d\.?)+/)   # => #<MatchData "2.5.0" 1:"0">
#     m.string                    # => "https://docs.ruby-lang.org/en/2.5.0/MatchData.html"
#     m.regexp                    # => /(\d\.?)+/
#     # entire matched substring:
#     m[0]                        # => "2.5.0"
#
#     # Working with unnamed captures
#     m = url.match(%r{([^/]+)/([^/]+)\.html$})
#     m.captures                  # => ["2.5.0", "MatchData"]
#     m[1]                        # => "2.5.0"
#     m.values_at(1, 2)           # => ["2.5.0", "MatchData"]
#
#     # Working with named captures
#     m = url.match(%r{(?<version>[^/]+)/(?<module>[^/]+)\.html$})
#     m.captures                  # => ["2.5.0", "MatchData"]
#     m.named_captures            # => {"version"=>"2.5.0", "module"=>"MatchData"}
#     m[:version]                 # => "2.5.0"
#     m.values_at(:version, :module)
#                                 # => ["2.5.0", "MatchData"]
#     # Numerical indexes are working, too
#     m[1]                        # => "2.5.0"
#     m.values_at(1, 2)           # => ["2.5.0", "MatchData"]
#
# ## Global variables equivalence
#
# Parts of last MatchData (returned by Regexp.last_match) are also aliased as
# global variables:
#
# *   `$~` is Regexp.last_match;
# *   `$&` is Regexp.last_match`[ 0 ]`;
# *   `$1`, `$2`, and so on are Regexp.last_match`[ i ]` (captures by number);
# *   `$`` is Regexp.last_match`.pre_match`;
# *   `$'` is Regexp.last_match`.post_match`;
# *   `$+` is Regexp.last_match`[ -1 ]` (the last capture).
#
#
# See also "Special global variables" section in Regexp documentation.
#
class MatchData
  public

  # <!-- rdoc-file=re.c -->
  # Equality---Two matchdata are equal if their target strings, patterns, and
  # matched positions are identical.
  #
  def ==: (untyped other) -> bool

  # <!--
  #   rdoc-file=re.c
  #   - mtch[i]               -> str or nil
  #   - mtch[start, length]   -> array
  #   - mtch[range]           -> array
  #   - mtch[name]            -> str or nil
  # -->
  # Match Reference -- MatchData acts as an array, and may be accessed using the
  # normal array indexing techniques.  `mtch[0]` is equivalent to the special
  # variable `$&`, and returns the entire matched string.  `mtch[1]`, `mtch[2]`,
  # and so on return the values of the matched backreferences (portions of the
  # pattern between parentheses).
  #
  #     m = /(.)(.)(\d+)(\d)/.match("THX1138.")
  #     m          #=> #<MatchData "HX1138" 1:"H" 2:"X" 3:"113" 4:"8">
  #     m[0]       #=> "HX1138"
  #     m[1, 2]    #=> ["H", "X"]
  #     m[1..3]    #=> ["H", "X", "113"]
  #     m[-3, 2]   #=> ["X", "113"]
  #
  #     m = /(?<foo>a+)b/.match("ccaaab")
  #     m          #=> #<MatchData "aaab" foo:"aaa">
  #     m["foo"]   #=> "aaa"
  #     m[:foo]    #=> "aaa"
  #
  def []: (Integer idx) -> String?
        | (Integer start, Integer length) -> ::Array[String?]
        | (::Range[Integer] range) -> ::Array[String?]
        | (String | Symbol name) -> String?

  # <!--
  #   rdoc-file=re.c
  #   - mtch.begin(n)   -> integer
  # -->
  # Returns the offset of the start of the *n*th element of the match array in the
  # string. *n* can be a string or symbol to reference a named capture.
  #
  #     m = /(.)(.)(\d+)(\d)/.match("THX1138.")
  #     m.begin(0)       #=> 1
  #     m.begin(2)       #=> 2
  #
  #     m = /(?<foo>.)(.)(?<bar>.)/.match("hoge")
  #     p m.begin(:foo)  #=> 0
  #     p m.begin(:bar)  #=> 2
  #
  def begin: (Integer | String | Symbol n_or_name) -> Integer?

  # <!--
  #   rdoc-file=re.c
  #   - mtch.captures   -> array
  # -->
  # Returns the array of captures; equivalent to `mtch.to_a[1..-1]`.
  #
  #     f1,f2,f3,f4 = /(.)(.)(\d+)(\d)/.match("THX1138.").captures
  #     f1    #=> "H"
  #     f2    #=> "X"
  #     f3    #=> "113"
  #     f4    #=> "8"
  #
  def captures: () -> ::Array[String?]

  # <!--
  #   rdoc-file=re.c
  #   - mtch.end(n)   -> integer
  # -->
  # Returns the offset of the character immediately following the end of the *n*th
  # element of the match array in the string. *n* can be a string or symbol to
  # reference a named capture.
  #
  #     m = /(.)(.)(\d+)(\d)/.match("THX1138.")
  #     m.end(0)         #=> 7
  #     m.end(2)         #=> 3
  #
  #     m = /(?<foo>.)(.)(?<bar>.)/.match("hoge")
  #     p m.end(:foo)    #=> 1
  #     p m.end(:bar)    #=> 3
  #
  def end: (Integer | String | Symbol n_or_name) -> Integer?

  # <!--
  #   rdoc-file=re.c
  #   - mtch == mtch2   -> true or false
  #   - mtch.eql?(mtch2)   -> true or false
  # -->
  # Equality---Two matchdata are equal if their target strings, patterns, and
  # matched positions are identical.
  #
  def eql?: (untyped other) -> bool

  # <!--
  #   rdoc-file=re.c
  #   - mtch.hash   -> integer
  # -->
  # Produce a hash based on the target string, regexp and matched positions of
  # this matchdata.
  #
  # See also Object#hash.
  #
  def hash: () -> Integer

  # <!--
  #   rdoc-file=re.c
  #   - mtch.inspect   -> str
  # -->
  # Returns a printable version of *mtch*.
  #
  #     puts /.$/.match("foo").inspect
  #     #=> #<MatchData "o">
  #
  #     puts /(.)(.)(.)/.match("foo").inspect
  #     #=> #<MatchData "foo" 1:"f" 2:"o" 3:"o">
  #
  #     puts /(.)(.)?(.)/.match("fo").inspect
  #     #=> #<MatchData "fo" 1:"f" 2:nil 3:"o">
  #
  #     puts /(?<foo>.)(?<bar>.)(?<baz>.)/.match("hoge").inspect
  #     #=> #<MatchData "hog" foo:"h" bar:"o" baz:"g">
  #
  def inspect: () -> String

  # <!-- rdoc-file=re.c -->
  # Returns the number of elements in the match array.
  #
  #     m = /(.)(.)(\d+)(\d)/.match("THX1138.")
  #     m.length   #=> 5
  #     m.size     #=> 5
  #
  def length: () -> Integer

  # <!--
  #   rdoc-file=re.c
  #   - mtch.named_captures -> hash
  # -->
  # Returns a Hash using named capture.
  #
  # A key of the hash is a name of the named captures. A value of the hash is a
  # string of last successful capture of corresponding group.
  #
  #     m = /(?<a>.)(?<b>.)/.match("01")
  #     m.named_captures #=> {"a" => "0", "b" => "1"}
  #
  #     m = /(?<a>.)(?<b>.)?/.match("0")
  #     m.named_captures #=> {"a" => "0", "b" => nil}
  #
  #     m = /(?<a>.)(?<a>.)/.match("01")
  #     m.named_captures #=> {"a" => "1"}
  #
  #     m = /(?<a>x)|(?<a>y)/.match("x")
  #     m.named_captures #=> {"a" => "x"}
  #
  def named_captures: () -> ::Hash[String, String?]

  # <!--
  #   rdoc-file=re.c
  #   - mtch.names   -> [name1, name2, ...]
  # -->
  # Returns a list of names of captures as an array of strings. This is the same
  # as mtch.regexp.names.
  #
  #     /(?<foo>.)(?<bar>.)(?<baz>.)/.match("hoge").names
  #     #=> ["foo", "bar", "baz"]
  #
  #     m = /(?<x>.)(?<y>.)?/.match("a") #=> #<MatchData "a" x:"a" y:nil>
  #     m.names                          #=> ["x", "y"]
  #
  def names: () -> ::Array[String]

  # <!--
  #   rdoc-file=re.c
  #   - mtch.match(n)   -> string or nil
  # -->
  # Returns the captured substring corresponding to the argument. *n* can be a
  # string or symbol to reference a named capture.
  #
  #     m = /(.)(.)(\d+)(\d)(\w)?/.match("THX1138.")
  #     m.match(0)       #=> "HX1138"
  #     m.match(4)       #=> "8"
  #     m.match(5)       #=> nil
  #
  #     m = /(?<foo>.)(.)(?<bar>.+)/.match("hoge")
  #     m.match(:foo)    #=> "h"
  #     m.match(:bar)    #=> "ge"
  #
  def match: (int | String | Symbol) -> String?

  # <!--
  #   rdoc-file=re.c
  #   - mtch.match_length(n)   -> array
  # -->
  # Returns the length of the captured substring corresponding to the argument.
  # *n* can be a string or symbol to reference a named capture.
  #
  #     m = /(.)(.)(\d+)(\d)(\w)?/.match("THX1138.")
  #     m.match_length(0)       #=> 6
  #     m.match_length(4)       #=> 1
  #     m.match_length(5)       #=> nil
  #
  #     m = /(?<foo>.)(.)(?<bar>.+)/.match("hoge")
  #     m.match_length(:foo)    #=> 1
  #     m.match_length(:bar)    #=> 2
  #
  def match_length: (int | String | Symbol) -> Integer?

  # <!--
  #   rdoc-file=re.c
  #   - mtch.offset(n)   -> array
  # -->
  # Returns a two-element array containing the beginning and ending offsets of the
  # *n*th match. *n* can be a string or symbol to reference a named capture.
  #
  #     m = /(.)(.)(\d+)(\d)/.match("THX1138.")
  #     m.offset(0)      #=> [1, 7]
  #     m.offset(4)      #=> [6, 7]
  #
  #     m = /(?<foo>.)(.)(?<bar>.)/.match("hoge")
  #     p m.offset(:foo) #=> [0, 1]
  #     p m.offset(:bar) #=> [2, 3]
  #
  def offset: (Integer | Symbol | String n_or_name) -> ([ Integer, Integer ] | [ nil, nil ])

  # <!--
  #   rdoc-file=re.c
  #   - mtch.post_match   -> str
  # -->
  # Returns the portion of the original string after the current match. Equivalent
  # to the special variable `$'`.
  #
  #     m = /(.)(.)(\d+)(\d)/.match("THX1138: The Movie")
  #     m.post_match   #=> ": The Movie"
  #
  def post_match: () -> String

  # <!--
  #   rdoc-file=re.c
  #   - mtch.pre_match   -> str
  # -->
  # Returns the portion of the original string before the current match.
  # Equivalent to the special variable `$``.
  #
  #     m = /(.)(.)(\d+)(\d)/.match("THX1138.")
  #     m.pre_match   #=> "T"
  #
  def pre_match: () -> String

  # <!--
  #   rdoc-file=re.c
  #   - mtch.regexp   -> regexp
  # -->
  # Returns the regexp.
  #
  #     m = /a.*b/.match("abc")
  #     m.regexp #=> /a.*b/
  #
  def regexp: () -> Regexp

  # <!--
  #   rdoc-file=re.c
  #   - mtch.length   -> integer
  #   - mtch.size     -> integer
  # -->
  # Returns the number of elements in the match array.
  #
  #     m = /(.)(.)(\d+)(\d)/.match("THX1138.")
  #     m.length   #=> 5
  #     m.size     #=> 5
  #
  def size: () -> Integer

  # <!--
  #   rdoc-file=re.c
  #   - mtch.string   -> str
  # -->
  # Returns a frozen copy of the string passed in to `match`.
  #
  #     m = /(.)(.)(\d+)(\d)/.match("THX1138.")
  #     m.string   #=> "THX1138."
  #
  def string: () -> String

  # <!--
  #   rdoc-file=re.c
  #   - mtch.to_a   -> anArray
  # -->
  # Returns the array of matches.
  #
  #     m = /(.)(.)(\d+)(\d)/.match("THX1138.")
  #     m.to_a   #=> ["HX1138", "H", "X", "113", "8"]
  #
  # Because `to_a` is called when expanding `*`*variable*, there's a useful
  # assignment shortcut for extracting matched fields. This is slightly slower
  # than accessing the fields directly (as an intermediate array is generated).
  #
  #     all,f1,f2,f3 = * /(.)(.)(\d+)(\d)/.match("THX1138.")
  #     all   #=> "HX1138"
  #     f1    #=> "H"
  #     f2    #=> "X"
  #     f3    #=> "113"
  #
  def to_a: () -> ::Array[String?]

  # <!--
  #   rdoc-file=re.c
  #   - mtch.to_s   -> str
  # -->
  # Returns the entire matched string.
  #
  #     m = /(.)(.)(\d+)(\d)/.match("THX1138.")
  #     m.to_s   #=> "HX1138"
  #
  def to_s: () -> String

  # <!--
  #   rdoc-file=re.c
  #   - mtch.values_at(index, ...)   -> array
  # -->
  # Uses each *index* to access the matching values, returning an array of the
  # corresponding matches.
  #
  #     m = /(.)(.)(\d+)(\d)/.match("THX1138: The Movie")
  #     m.to_a               #=> ["HX1138", "H", "X", "113", "8"]
  #     m.values_at(0, 2, -2)   #=> ["HX1138", "X", "113"]
  #     m.values_at(1..2, -1)   #=> ["H", "X", "8"]
  #
  #     m = /(?<a>\d+) *(?<op>[+\-*\/]) *(?<b>\d+)/.match("1 + 2")
  #     m.to_a               #=> ["1 + 2", "1", "+", "2"]
  #     m.values_at(:a, :b, :op) #=> ["1", "2", "+"]
  #
  def values_at: (*Integer | Symbol | String n_or_name) -> ::Array[String?]

  private

  def initialize_copy: (self object) -> void
end
