Issue #21859 has been updated by Eregon (Benoit Daloze). Status changed from Open to Closed An interesting fact is TruffleRuby/TRegex seems to report exactly the opposite for these 4 Regexp whether they are linear: ``` truffleruby 33.0.1 (2026-01-20), like ruby 3.3.7, Oracle GraalVM Native [x86_64-linux] irb(main):001> Regexp.linear_time?(/(?=(a))/) => true irb(main):002> Regexp.linear_time?(/(?<=(a))/) => false irb(main):003> Regexp.linear_time?(/x+(?=(a))/) => true irb(main):004> Regexp.linear_time?(/x+(?<=(a))/) => false ``` ``` ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [x86_64-linux] irb(main):001> Regexp.linear_time?(/(?=(a))/) => false irb(main):002> Regexp.linear_time?(/(?<=(a))/) => true irb(main):003> Regexp.linear_time?(/x+(?=(a))/) => false irb(main):004> Regexp.linear_time?(/x+(?<=(a))/) => true ``` I think that means it depends a lot on the specifics of the Regexp engine implementation. I made a summary back then in https://bugs.ruby-lang.org/issues/19104#note-3 (FWIW I think `/x+(?<=(a))/` can never match, it would need to match both 'x' and 'a' for the same input character)
Should this issue be changed to a feature request?
I think we should close this rather. And if you want something specific and have a use for it then filing a new feature request is best. FWIW I saw on 4.0.1 `Regexp.linear_time?(/(?=a)/)` is true but `Regexp.linear_time?(/(?=(a))/)` is false. I don't think capture groups in lookahead or lookbehind are common though. ---------------------------------------- Bug #21859: Inconsistent behaviors in Regexp lookbehind/lookahead with capture groups https://bugs.ruby-lang.org/issues/21859#change-116268 * Author: trinistr (Alexander Bulancov) * Status: Closed * 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/