diff --git a/ext/jruby/org/jruby/ext/strscan/RubyStringScanner.java b/ext/jruby/org/jruby/ext/strscan/RubyStringScanner.java index 3baa6773eb..933b82e4b9 100644 --- a/ext/jruby/org/jruby/ext/strscan/RubyStringScanner.java +++ b/ext/jruby/org/jruby/ext/strscan/RubyStringScanner.java @@ -857,7 +857,7 @@ public IRubyObject fixed_anchor_p(ThreadContext context) { } @JRubyMethod(name = "named_captures") - public IRubyObject named_captured(ThreadContext context) { + public IRubyObject named_captures(ThreadContext context) { Ruby runtime = context.runtime; IRubyObject nil = context.nil; @@ -872,7 +872,10 @@ public IRubyObject named_captured(ThreadContext context) { IRubyObject value = nil; for (int i : nameEntry.getBackRefs()) { - value = extractRegion(context, i); + IRubyObject v = extractRegion(context, i); + if (v != nil) { + value = v; + } } int nameP = nameEntry.nameP; diff --git a/ext/strscan/strscan.c b/ext/strscan/strscan.c index 2824eeb4d9..9d6bd4c601 100644 --- a/ext/strscan/strscan.c +++ b/ext/strscan/strscan.c @@ -2211,7 +2211,10 @@ named_captures_iter(const OnigUChar *name, VALUE value = RUBY_Qnil; int i; for (i = 0; i < back_num; i++) { - value = strscan_aref(data->self, INT2NUM(back_refs[i])); + VALUE v = strscan_aref(data->self, INT2NUM(back_refs[i])); + if (!RB_NIL_P(v)) { + value = v; + } } rb_hash_aset(data->captures, key, value); return 0; diff --git a/test/strscan/test_stringscanner.rb b/test/strscan/test_stringscanner.rb index 0a28d92368..e895a8382b 100644 --- a/test/strscan/test_stringscanner.rb +++ b/test/strscan/test_stringscanner.rb @@ -967,6 +967,12 @@ def test_named_captures assert_equal({}, scan.named_captures) end + def test_named_captures_same_name_union + scan = StringScanner.new("123") + assert_equal(1, scan.match?(/(?0)|(?1)|(?2)/)) + assert_equal({"number" => "1"}, scan.named_captures) + end + def test_scan_integer s = create_string_scanner('abc') assert_equal(3, s.match?(/(?abc)/)) # set named_captures