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') # => #<MatchData "ab" 1:nil> regexp.match('aabaa') # => #<MatchData "ab" 1:nil> regexp = /[a-z]{2}(?!([a-z])\1)/ regexp.match('aabaa') # => #<MatchData "aa" 1:nil> ``` ---------------------------------------- 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> /(?<!(a))b/ /home/alex/.local/share/mise/installs/ruby/4.0.1/lib/ruby/gems/4.0.0/gems/irb-1.16.0/exe/irb:9:in '<top (required)>': (irb):2: invalid pattern in look-behind: /(?<!(a))b/ (SyntaxError) ``` I believe such a capture group can never capture anything, so it probably should be an error in both cases. -- https://bugs.ruby-lang.org/