🐈

[Bug #21288]MatchData#named_capturesとStringScanner#named_capturesのバグ報告

に公開

[Bug #21288] StringScanner#named_captures overrides matched captures with unmatched captures

  • 正規表現の名前付きキャプチャで同じ名前のキャプチャが複数ある場合に MatchData#named_capturesStringScanner#named_captures で挙動が異なるというバグ報告
    • MatchData の方はどちらか一方でマッチされた場合はその値をキャプチャする
    • StringScanner の方は一番最後に定義されたキャプチャしかみない
require 'strscan'

# test という名前でキャプチャが2つある
re = /(?<test>value)|(?<test>other branch)/

# MatchData#named_captures ではいずれかのマッチした文字列がキャプチャされる
p "value".match(re).named_captures        # => {"test" => "value"}
p "other branch".match(re).named_captures # => {"test" => "other branch"}

# 一方で StringScanner#named_captures の方は常に (?<test>other branch) でキャプチャされた値のみを参照している
# なので value の方でマッチしてもキャプチャされる値は nil なってしまう
scanner = StringScanner.new("value")
scanner.scan(re)
p scanner.named_captures #=> {"test" => nil}

scanner = StringScanner.new('other branch')
scanner.scan(re)
p scanner.named_captures #=> {"test" => "other branch"}
  • この不具合は strscan 3.1.4 で MatchData#named_captures の挙動と同じになるように修正された
require 'strscan'

# test という名前でキャプチャが2つある
re = /(?<test>value)|(?<test>other branch)/

scanner = StringScanner.new("value")
scanner.scan(re)
p scanner.named_captures
# strscan 3.1.4 以前 => {"test" => nil}
# strscan 3.1.4 以降 => {"test" => "value"}
GitHubで編集を提案

Discussion