Skip to content

Commit

Permalink
MatchData: fixed #4565: rename size to group_size and fix size behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
makenowjust authored and asterite committed Jun 14, 2017
1 parent 526837e commit be85fa4
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 20 deletions.
6 changes: 6 additions & 0 deletions spec/std/match_data_spec.cr
Expand Up @@ -13,6 +13,12 @@ describe "Regex::MatchData" do
/fox/.match("the fox").to_s.should eq(%(#<Regex::MatchData "fox">))
end

it "does size" do
"Crystal".match(/[p-s]/).not_nil!.size.should eq(1)
"Crystal".match(/r(ys)/).not_nil!.size.should eq(2)
"Crystal".match(/r(ys)(?<ok>ta)/).not_nil!.size.should eq(3)
end

describe "#[]" do
it "captures empty group" do
("foo" =~ /(?<g1>z?)foo/).should eq(0)
Expand Down
6 changes: 3 additions & 3 deletions spec/std/regex_spec.cr
Expand Up @@ -8,7 +8,7 @@ describe "Regex" do

it "does =~" do
(/foo/ =~ "bar foo baz").should eq(4)
$~.size.should eq(0)
$~.group_size.should eq(0)
end

it "does inspect" do
Expand Down Expand Up @@ -64,7 +64,7 @@ describe "Regex" do

it "matches with =~ and captures" do
("fooba" =~ /f(o+)(bar?)/).should eq(0)
$~.size.should eq(2)
$~.group_size.should eq(2)
$1.should eq("oo")
$2.should eq("ba")
end
Expand All @@ -77,7 +77,7 @@ describe "Regex" do
it "matches with === and captures" do
"foo" =~ /foo/
(/f(o+)(bar?)/ === "fooba").should be_true
$~.size.should eq(2)
$~.group_size.should eq(2)
$1.should eq("oo")
$2.should eq("ba")
end
Expand Down
2 changes: 1 addition & 1 deletion spec/std/string_spec.cr
Expand Up @@ -1779,7 +1779,7 @@ describe "String" do

it "matches empty string" do
match = "".match(/.*/).not_nil!
match.size.should eq(0)
match.group_size.should eq(0)
match[0].should eq("")
end

Expand Down
42 changes: 26 additions & 16 deletions src/regex/match_data.cr
Expand Up @@ -26,11 +26,11 @@ class Regex
# Returns the number of capture groups, including named capture groups.
#
# ```
# "Crystal".match(/[p-s]/).not_nil!.size # => 0
# "Crystal".match(/r(ys)/).not_nil!.size # => 1
# "Crystal".match(/r(ys)(?<ok>ta)/).not_nil!.size # => 2
# "Crystal".match(/[p-s]/).not_nil!.group_size # => 0
# "Crystal".match(/r(ys)/).not_nil!.group_size # => 1
# "Crystal".match(/r(ys)(?<ok>ta)/).not_nil!.group_size # => 2
# ```
getter size : Int32
getter group_size : Int32

# Returns the original string.
#
Expand All @@ -40,7 +40,18 @@ class Regex
getter string : String

# :nodoc:
def initialize(@regex : Regex, @code : LibPCRE::Pcre, @string : String, @pos : Int32, @ovector : Int32*, @size : Int32)
def initialize(@regex : Regex, @code : LibPCRE::Pcre, @string : String, @pos : Int32, @ovector : Int32*, @group_size : Int32)
end

# Returns the number of elements in this match object.
#
# ```
# "Crystal".match(/[p-s]/).not_nil!.size # => 1
# "Crystal".match(/r(ys)/).not_nil!.size # => 2
# "Crystal".match(/r(ys)(?<ok>ta)/).not_nil!.size # => 3
# ```
def size
group_size + 1
end

# Return the position of the first character of the *n*th match.
Expand Down Expand Up @@ -204,7 +215,7 @@ class Regex
name_table = @regex.name_table

caps = [] of String?
(1..size).each do |i|
(1...size).each do |i|
caps << self[i]? unless name_table.has_key? i
end

Expand All @@ -226,7 +237,7 @@ class Regex
name_table = @regex.name_table

caps = {} of String => String?
(1..size).each do |i|
(1...size).each do |i|
if name = name_table[i]?
caps[name] = self[i]?
end
Expand All @@ -247,7 +258,7 @@ class Regex
# match.to_a # => ["Cr", "Cr", nil]
# ```
def to_a
(0..size).map { |i| self[i]? }
(0...size).map { |i| self[i]? }
end

# Convert this match data into a hash.
Expand All @@ -265,7 +276,7 @@ class Regex
name_table = @regex.name_table

hash = {} of (String | Int32) => String?
(0..size).each do |i|
(0...size).each do |i|
hash[name_table.fetch(i) { i }] = self[i]?
end

Expand All @@ -281,13 +292,12 @@ class Regex

io << "#<Regex::MatchData "
self[0].inspect(io)
if size > 0
if size > 1
io << " "
size.times do |i|
io << " " if i > 0
io << name_table.fetch(i + 1) { i + 1 }
(1...size).join " ", io do |i|
io << name_table.fetch(i) { i }
io << ":"
self[i + 1]?.inspect(io)
self[i]?.inspect(io)
end
end
io << ">"
Expand All @@ -306,15 +316,15 @@ class Regex
return false unless regex == other.regex
return false unless string == other.string

return @ovector.memcmp(other.@ovector, (size + 1) * 2) == 0
return @ovector.memcmp(other.@ovector, size * 2) == 0
end

private def check_index_out_of_bounds(index)
raise_invalid_group_index(index) unless valid_group?(index)
end

private def valid_group?(index)
index <= @size
index < size
end

private def raise_invalid_group_index(index)
Expand Down

0 comments on commit be85fa4

Please sign in to comment.