From: "trinistr (Alexander Bulancov) via ruby-core" Date: 2026-02-03T16:11:44+00:00 Subject: [ruby-core:124666] [Ruby Bug#21859] Inconsistent behaviors in Regexp lookbehind/lookahead with capture groups Issue #21859 has been updated by trinistr (Alexander Bulancov). > I think `Regexp.linear_time?(/(?<=(a))/)` matches in linear time. I apologize, it seems I got distracted and forgot to actually check the execution times. But this is interesting behavior. Maybe constant-size lookahead can be optimized to also be linear? It seems strange to me that these cases are so similar but behave very differently. > Capture group in negative lookahead can capture and can be used inside negative lookahead. I've not been able to find a case where the capture group actually captures, not just overall regexp matches. Isn't it impossible? To match, regexp needs to satisfy *negative* lookahead, so there should *not be* anything to capture. ```ruby regexp = /(?!([a-z])\1)[a-z]{2}/ regexp.match('ab') # => # regexp.match('aabaa') # => # regexp = /[a-z]{2}(?!([a-z])\1)/ regexp.match('aabaa') # => # ``` ---------------------------------------- Bug #21859: Inconsistent behaviors in Regexp lookbehind/lookahead with capture groups https://bugs.ruby-lang.org/issues/21859#change-116261 * Author: trinistr (Alexander Bulancov) * Status: Open * ruby -v: ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [x86_64-linux] * Backport: 3.2: UNKNOWN, 3.3: UNKNOWN, 3.4: UNKNOWN, 4.0: UNKNOWN ---------------------------------------- First issue: `Regexp.linear_time?` is `false` for a positive lookahead with a capture, but `true` for a positive lookbehind: ```ruby irb(main):002> Regexp.linear_time?(/(?=(a))/) => false irb(main):003> Regexp.linear_time?(/(?<=(a))/) => true ``` This should be `false` in both cases. Second issue: Capture group is allowed in a negative lookahead, but causes a `SyntaxError` in a negative lookbehind: ```ruby irb(main):001> /(?!(a))b/ => /(?!(a))b/ irb(main):002> /(?': (irb):2: invalid pattern in look-behind: /(?