Skip to content

Bump fancy-regex from 0.14.0 to 0.20.1 - #187

Open
dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/cargo/fancy-regex-0.20.1
Open

dependabot[bot] wants to merge 1 commit into
mainfrom
dependabot/cargo/fancy-regex-0.20.1

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Nov 13, 2026

Copy link
Copy Markdown
Contributor

Bumps fancy-regex from 0.14.0 to 0.20.1.

Release notes

Sourced from fancy-regex's releases.

0.20.1

Added

  • A new Expr::has_descendant_or_self method to easily traverse the Expr descendants to find an Expr matching a predicate. (#319)
  • Add a RegexOptionsBuilder::optimize / RegexBuilder::optimize flag to disable the expression-tree optimization pass (enabled by default), and rework it into two tiers: optimize() now takes an OptimizeOptions struct with a find_not_empty flag that skips only the KeepOut (\K) and trailing-lookahead rewrites, while the safe rewrites still apply — so find_not_empty patterns benefit from them instead of skipping the whole pass. The decision on whether to optimize is centralized on RegexOptions::should_optimize and forwarded to the prefilter helpers (start_bytes, required_bytes) so they analyze the same tree as the compile path. (#323)
  • Support control character escapes \cX and \C-X in Oniguruma mode, e.g. \ca matches \x01 and \c\\ matches \x1C, both inside and outside of character classes. Without Oniguruma mode they are still invalid escapes. (#320)

Changed

Fixed

  • Positive lookaheads are now atomic, as in Oniguruma and PCRE: once a lookahead has matched, a later failure no longer backtracks into it to try another way of matching it. For example (?=x|(x))\1x no longer matches xx. (#313)
  • A hard variable-length lookbehind no longer reuses the candidate start positions left behind by a previous lookbehind that matched (or by a negative lookbehind whose body matched), which gave wrong results such as (b*)(?<!\1)c matching abc, or hit the backtrack limit when a pattern had two such lookbehinds, like (a*)b(?<=\1b)(c*)d(?<=\2d). (#314)
  • A repetition with a minimum count whose body can match an empty string (e.g. (?:a|(?=b)){2,}) could stop before reaching the minimum when it ran again at a position its previous run had reached, for example inside a repeated lookahead: (?:(?=(?:a|(?=b)){2,})a){2} matched aa. (#312)
  • A {n,} repetition whose body can match an empty string ended as soon as an iteration matched empty, even below the minimum. When the first iteration matched empty, the last required one now still runs, so (?:(?=^)a*){2,}b matches aab. A body that reads a capture group it sets itself can match differently in the next iteration, so there all required iterations run, and ^(?:(?(1)a|())){3,}$ no longer matches an empty string. (#325)
  • A conditional whose condition fails no longer leaves its entry on the VM's explicit stack. Before, an enclosing atomic group or possessive repeat read that entry at its end and kept its backtrack branches: (z)?(?>a*(?(1)x))a matched "aaa". (#316)
  • A conditional whose true branch is a group of alternatives, such as (?(1)(?:a|b)), was parsed as (?(1)a|b), so b became the false branch. (#315)
  • Inline flags set inside a capturing, named, atomic, lookaround, conditional or absent group, like (a(?i)b)c, now end with the group. Before, they leaked to the rest of the pattern, so (a(?i)b)c matched aBC and (?x)G(o(?-x)o) g did not ignore the spaces after the group. Only (?:...) and (?flags:...) restored them. (#317)
  • In Oniguruma mode, {,} is now literal text, as in Oniguruma, instead of being parsed as {0,}. For example (?:ab){,} matches ab{,}. {,n} is still {0,n}, and without Oniguruma mode {,} is unchanged. (#321)
  • In Oniguruma mode, a ? after an interval with swapped limits, like a{3,2}?, is now another quantifier, as in Oniguruma, so it makes the possessive a{2,3} optional. Before, it made the repeat lazy, so a{3,2}? matched aa in aaa and didn't match an empty string. A ?, * or + after a repeated empty group, like in (?:)** or (?:){3,2}?, is now dropped along with it instead of failing to parse. (#322)
  • In Oniguruma mode, a ? after a fixed interval, like a{3}?, is now another quantifier, as in Oniguruma, so a{3}? means (?:a{3})?. Before, it made the repeat lazy, which doesn't change anything for a fixed count, so a{3}? didn't match aa and a{3}?? matched aaa instead of an empty string. a{3,3}? is still lazy, and without Oniguruma mode a{3}? is unchanged.
  • A backref or conditional inside the group it refers to now sees the group's previous capture, as in PCRE and Perl. Before, it saw the new start of the group with the end of its previous capture, so (?:(\1|a)b){2} panicked on abab and ^((?(1)b|a))$ matched b but not a. (#328)

0.20.0

Added

  • Add RegexOptionsBuilder::build_delegate_prefilter to disable building the prefilter (#282)
  • Add RegexOptionsBuilder::start_bytes that returns the first bytes that can match a pattern so you can build your own prefilter (#282)
  • Add RegexOptionsBuilder::required_bytes that returns the required bytes for a pattern to match (#287)
  • Add RegexOptionsBuilder::max_prog_size / RegexBuilder::max_prog_size to cap the number of VM instructions emitted while compiling. Subroutine calls are inlined at compile time, so a self- or mutually-recursive pattern can expand without bound even while the recursion-depth cap is respected; this bounds the emitted instruction vector instead. Exceeding the cap returns CompileError::PatternTooComplex. Disabled by default. (#298)
  • Implement support for variable length hard lookbehinds, by seeking backwards to candidate match start positions and then matching forward as usual. The reverse DFA honours delegate_size_limit and delegate_dfa_size_limit. (#286, #309)
  • Add RegexOptionsBuilder::delegate_dfa_skip_cache_capacity_check / RegexBuilder::delegate_dfa_skip_cache_capacity_check, enabled by default. Setting it to false makes the reverse DFA of a variable-length lookbehind strictly honour delegate_dfa_size_limit, so a too-small limit becomes a compile error. (#309)
  • Add ByteSet::is_subset to test whether one byte set is a subset of another. (#289)

Changed

  • If a lookbehind consists of an Alt containing only easy expressions and at least 4 branches (and no capture groups), compile it as a variable lookbehind (if the feature is enabled) instead of trying every branch as its own const-size lookbehind. One reverse-DFA delegate over the whole alternation is much cheaper per attempt, and grants a perf boost. (#285)
  • Word boundaries (\b, \B, \<, \>) are no longer marked hard outside a lookbehind. regex-automata supports them, so a pattern like \b(?:foo|bar|baz)\b now compiles to a single delegated engine instead of one branch per alternative — previously it grew linearly with the number of alternatives. They remain hard inside a lookbehind, since regex-automata's reverse DFA can't run a variable-length lookbehind on unicode haystacks. The half-boundary variants (\<, \>) and \Z are still always hard. (#311)
  • The parser now tracks every capture group declared with the same name; Regex::capture_names reports the name for each of them, and named backrefs resolve to the last group with that name (#177)

Fixed

  • The reverse lazy DFA built for a variable-length lookbehind failed to compile when it needed a larger cache capacity than the configured delegate_dfa_size_limit (or the default of 2 MiB); for example (?<=\p{L}{99,100})x failed to compile with default settings. The capacity is now rounded up to the minimum required. Ordinary delegates were not affected because the meta engine falls back to another engine when the lazy DFA cannot be built. (#309)
  • delegate_dfa_size_limit now sets the lazy DFA cache capacity (hybrid_cache_capacity) as documented, instead of the fully compiled DFA size limit. It had been forwarded to the wrong regex-automata option since the switch from the regex crate. (#307)
  • Fix bug with literal bytes being used in unicode mode unexpectedly: in Unicode mode, \xHH escapes above 0x7F now match the Unicode codepoint (as UTF-8 bytes) instead of the raw byte, so e.g. \xFF matches ÿ rather than the byte 0xFF. In bytes modes the raw byte is matched as before. (#292)
  • Fix case-insensitive prefilter computation for non-ASCII class ranges that fold to characters with different lead bytes (e.g. (?i)[à-ÿ]), which previously could miss candidate start positions. (#296)
  • Fix ^ / $ and their multi-line variants matching at the start/end of arbitrary-byte haystacks in Ascii and UnicodeBytes bytes modes, where the match position was not a UTF-8 codepoint boundary. (#300)
  • Fix seek optimization dropping matches when conditionals had empty branches, e.g. (a)?b(?(1)c) no longer fails to match b. (#304)
  • Fix hard variable-length lookbehind reverse DFA ignoring the caller's Unicode and bytes-mode settings, giving wrong results in non-Unicode bytes modes (e.g. (?<=(\w+)\1)x on ééx). (#310)

0.19.2

Added

  • Add a leftmost_longest feature (off by default) that adds a method to the RegexBuilder/RegexOptionsBuilder for building a VM which would operate in leftmost-longest match mode instead of the regular leftmost-first mode. Useful for POSIX compliance. (#281)

Changed

Fixed

0.19.1

Added

  • Add a perf-dfa-full feature (off by default, mirroring the regex crate) that lets regex-automata eagerly build fully compiled dense DFAs for small patterns, for workloads that compile few regexes and match them very heavily (#272)

... (truncated)

Changelog

Sourced from fancy-regex's changelog.

[0.20.1] - 2026-11-09

Added

  • A new Expr::has_descendant_or_self method to easily traverse the Expr descendants to find an Expr matching a predicate. (#319)
  • Add a RegexOptionsBuilder::optimize / RegexBuilder::optimize flag to disable the expression-tree optimization pass (enabled by default), and rework it into two tiers: optimize() now takes an OptimizeOptions struct with a find_not_empty flag that skips only the KeepOut (\K) and trailing-lookahead rewrites, while the safe rewrites still apply — so find_not_empty patterns benefit from them instead of skipping the whole pass. The decision on whether to optimize is centralized on RegexOptions::should_optimize and forwarded to the prefilter helpers (start_bytes, required_bytes) so they analyze the same tree as the compile path. (#323)
  • Support control character escapes \cX and \C-X in Oniguruma mode, e.g. \ca matches \x01 and \c\\ matches \x1C, both inside and outside of character classes. Without Oniguruma mode they are still invalid escapes. (#320)

Changed

Fixed

  • Positive lookaheads are now atomic, as in Oniguruma and PCRE: once a lookahead has matched, a later failure no longer backtracks into it to try another way of matching it. For example (?=x|(x))\1x no longer matches xx. (#313)
  • A hard variable-length lookbehind no longer reuses the candidate start positions left behind by a previous lookbehind that matched (or by a negative lookbehind whose body matched), which gave wrong results such as (b*)(?<!\1)c matching abc, or hit the backtrack limit when a pattern had two such lookbehinds, like (a*)b(?<=\1b)(c*)d(?<=\2d). (#314)
  • A repetition with a minimum count whose body can match an empty string (e.g. (?:a|(?=b)){2,}) could stop before reaching the minimum when it ran again at a position its previous run had reached, for example inside a repeated lookahead: (?:(?=(?:a|(?=b)){2,})a){2} matched aa. (#312)
  • A {n,} repetition whose body can match an empty string ended as soon as an iteration matched empty, even below the minimum. When the first iteration matched empty, the last required one now still runs, so (?:(?=^)a*){2,}b matches aab. A body that reads a capture group it sets itself can match differently in the next iteration, so there all required iterations run, and ^(?:(?(1)a|())){3,}$ no longer matches an empty string. (#325)
  • A conditional whose condition fails no longer leaves its entry on the VM's explicit stack. Before, an enclosing atomic group or possessive repeat read that entry at its end and kept its backtrack branches: (z)?(?>a*(?(1)x))a matched "aaa". (#316)
  • A conditional whose true branch is a group of alternatives, such as (?(1)(?:a|b)), was parsed as (?(1)a|b), so b became the false branch. (#315)
  • Inline flags set inside a capturing, named, atomic, lookaround, conditional or absent group, like (a(?i)b)c, now end with the group. Before, they leaked to the rest of the pattern, so (a(?i)b)c matched aBC and (?x)G(o(?-x)o) g did not ignore the spaces after the group. Only (?:...) and (?flags:...) restored them. (#317)
  • In Oniguruma mode, {,} is now literal text, as in Oniguruma, instead of being parsed as {0,}. For example (?:ab){,} matches ab{,}. {,n} is still {0,n}, and without Oniguruma mode {,} is unchanged. (#321)
  • In Oniguruma mode, a ? after an interval with swapped limits, like a{3,2}?, is now another quantifier, as in Oniguruma, so it makes the possessive a{2,3} optional. Before, it made the repeat lazy, so a{3,2}? matched aa in aaa and didn't match an empty string. A ?, * or + after a repeated empty group, like in (?:)** or (?:){3,2}?, is now dropped along with it instead of failing to parse. (#322)
  • In Oniguruma mode, a ? after a fixed interval, like a{3}?, is now another quantifier, as in Oniguruma, so a{3}? means (?:a{3})?. Before, it made the repeat lazy, which doesn't change anything for a fixed count, so a{3}? didn't match aa and a{3}?? matched aaa instead of an empty string. a{3,3}? is still lazy, and without Oniguruma mode a{3}? is unchanged.
  • A backref or conditional inside the group it refers to now sees the group's previous capture, as in PCRE and Perl. Before, it saw the new start of the group with the end of its previous capture, so (?:(\1|a)b){2} panicked on abab and ^((?(1)b|a))$ matched b but not a. (#328)

[0.20.0] - 2026-10-24

Added

  • Add RegexOptionsBuilder::build_delegate_prefilter to disable building the prefilter (#282)
  • Add RegexOptionsBuilder::start_bytes that returns the first bytes that can match a pattern so you can build your own prefilter (#282)
  • Add RegexOptionsBuilder::required_bytes that returns the required bytes for a pattern to match (#287)
  • Add RegexOptionsBuilder::max_prog_size / RegexBuilder::max_prog_size to cap the number of VM instructions emitted while compiling. Subroutine calls are inlined at compile time, so a self- or mutually-recursive pattern can expand without bound even while the recursion-depth cap is respected; this bounds the emitted instruction vector instead. Exceeding the cap returns CompileError::PatternTooComplex. Disabled by default. (#298)
  • Implement support for variable length hard lookbehinds, by seeking backwards to candidate match start positions and then matching forward as usual. The reverse DFA honours delegate_size_limit and delegate_dfa_size_limit. (#286, #309)
  • Add RegexOptionsBuilder::delegate_dfa_skip_cache_capacity_check / RegexBuilder::delegate_dfa_skip_cache_capacity_check, enabled by default. Setting it to false makes the reverse DFA of a variable-length lookbehind strictly honour delegate_dfa_size_limit, so a too-small limit becomes a compile error. (#309)
  • Add ByteSet::is_subset to test whether one byte set is a subset of another. (#289)

Changed

  • If a lookbehind consists of an Alt containing only easy expressions and at least 4 branches (and no capture groups), compile it as a variable lookbehind (if the feature is enabled) instead of trying every branch as its own const-size lookbehind. One reverse-DFA delegate over the whole alternation is much cheaper per attempt, and grants a perf boost. (#285)
  • Word boundaries (\b, \B, \<, \>) are no longer marked hard outside a lookbehind. regex-automata supports them, so a pattern like \b(?:foo|bar|baz)\b now compiles to a single delegated engine instead of one branch per alternative — previously it grew linearly with the number of alternatives. They remain hard inside a lookbehind, since regex-automata's reverse DFA can't run a variable-length lookbehind on unicode haystacks. The half-boundary variants and \Z are still always hard. (#311)
  • The parser now tracks every capture group declared with the same name; Regex::capture_names reports the name for each of them, and named backrefs resolve to the last group with that name (#177)

Fixed

  • The reverse lazy DFA built for a variable-length lookbehind failed to compile when it needed a larger cache capacity than the configured delegate_dfa_size_limit (or the default of 2 MiB); for example (?<=\p{L}{99,100})x failed to compile with default settings. The capacity is now rounded up to the minimum required. Ordinary delegates were not affected because the meta engine falls back to another engine when the lazy DFA cannot be built. (#309)
  • delegate_dfa_size_limit now sets the lazy DFA cache capacity (hybrid_cache_capacity) as documented, instead of the fully compiled DFA size limit. It had been forwarded to the wrong regex-automata option since the switch from the regex crate. (#307)
  • Fix bug with literal bytes being used in unicode mode unexpectedly: in Unicode mode, \xHH escapes above 0x7F now match the Unicode codepoint (as UTF-8 bytes) instead of the raw byte, so e.g. \xFF matches ÿ rather than the byte 0xFF. In bytes modes the raw byte is matched as before. (#292)
  • Fix case-insensitive prefilter computation for non-ASCII class ranges that fold to characters with different lead bytes (e.g. (?i)[à-ÿ]), which previously could miss candidate start positions. (#296)
  • Fix ^ / $ and their multi-line variants matching at the start/end of arbitrary-byte haystacks in Ascii and UnicodeBytes bytes modes, where the match position was not a UTF-8 codepoint boundary. (#300)
  • Fix seek optimization dropping matches when conditionals had empty branches, e.g. (a)?b(?(1)c) no longer fails to match b. (#304)
  • Fix hard variable-length lookbehind reverse DFA ignoring the caller's Unicode and bytes-mode settings, giving wrong results in non-Unicode bytes modes (e.g. (?<=(\w+)\1)x on ééx). (#310)

[0.19.2] - 2026-09-13

Added

  • Add a leftmost_longest feature (off by default) that adds a method to the RegexBuilder/RegexOptionsBuilder for building a VM which would operate in leftmost-longest match mode instead of the regular leftmost-first mode. Useful for POSIX compliance. (#281)

Changed

Fixed

  • Fix a panic in capture_names() for a pattern with a zero-repeated named group such as (?<n>a){0} (#275)
  • Literal bytes were being encoded as utf-8 in Ascii mode, now they match the exact byte literal

[0.19.1] - 2026-09-06

... (truncated)

Commits
  • a460c32 Version 0.20.1
  • 6832ab0 improve build_seek_pattern doc comments
  • 5df1aaa Rename misleading contains_word_boundary variable
  • 92e724e fix clippy warning
  • 1a1e52c Fix clippy too_many_arguments warning in build_seek_pattern_impl
  • 19c2796 Merge pull request #331 from Narek-Khachikyan/fix/lookbehind-boundary-candidates
  • 35859de Preserve quantified empty conditionals in reverse seek patterns
  • 965673e Address lookbehind compilation review feedback
  • 7b41315 Retry variable lookbehind starts after assertion failures
  • 950d36d Merge pull request #326 from fancy-regex/fix_quantifier_simplification_bug
  • Additional commits viewable in compare view

Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options

You can trigger Dependabot actions by commenting on this PR:

  • @dependabot rebase will rebase this PR
  • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
  • @dependabot show <dependency name> ignore conditions will show all of the ignore conditions of the specified dependency
  • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
  • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)

Bumps [fancy-regex](https://github.com/fancy-regex/fancy-regex) from 0.14.0 to 0.20.1.
- [Release notes](https://github.com/fancy-regex/fancy-regex/releases)
- [Changelog](https://github.com/fancy-regex/fancy-regex/blob/main/CHANGELOG.md)
- [Commits](fancy-regex/fancy-regex@0.14.0...0.20.1)

---
updated-dependencies:
- dependency-name: fancy-regex
  dependency-version: 0.20.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
@dependabot dependabot Bot added dependencies Pull requests that update a dependency file rust Pull requests that update rust code labels Nov 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file rust Pull requests that update rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants