Module regex/flags
Regex flags parsing and representation.
Internal to std/regex. RegexFlags is not public API — flags reach
the engine as the string argument of Regex.new_with_flags(pattern, flags).
Regex flags follow JavaScript syntax: "gi", "ms", "iu", etc. The
flag string is a set, so order does not matter, but a repeat is an error
(DuplicateFlag) rather than a no-op — a "gg" is far more likely a typo
than an intention.
Accepted flags, and what the engine actually does with each:
i— ignoreCase. HONOURED, but ASCII-only: the fold isA-Z→a-z(NfaVm._to_lower), soédoes not matchÉ. Setting it also discards the literal-prefix optimisation, because that scan is case-sensitive.m— multiline. HONOURED:^and$also match at\nboundaries.s— dotAll. HONOURED:.also matches\n.y— sticky. HONOURED: a match must start exactly where asked, and the literal-prefix skip is disabled so it cannot jump ahead.g— global. PARSED AND IGNORED. The engine has nolastIndex; "all occurrences" is a method choice (find_all/find_iter/replace_all), not a flag.u— unicode. PARSED AND IGNORED. The VM decodes UTF-8 and matches whole runes unconditionally, so there is no non-unicode mode to switch out of.
The last two are accepted for JavaScript source compatibility and are
filed as issues/stddoc-str-regex-g-and-u-flags-are-silently-ignored.md:
accepting a flag and doing nothing is worse than rejecting it, because
Regex.new_with_flags(p, "g").replace(...) looks like it replaces all and
does not.
Stability
unstable — and not public: RegexFlags is an internal type, reached only
through the flag STRING of Regex.new_with_flags. Two things have to be
settled before even that string is frozen: what g and u should do
(implement, or reject as invalid — either is a behaviour change for
existing callers), and whether i grows real Unicode case folding, which
would change what existing i patterns match. The Rust regex crate spells
these as inline (?i) groups rather than a trailing flag string; adopting
that would replace this module rather than extend it.
Types
The parsed flag set a Regex carries and hands to the VM on every
execution. Produced only by parse; Regex keeps one and never mutates
it, so a compiled pattern's flags are fixed for its lifetime.
Fields
| Name | Type | Description |
|---|---|---|
global | bool |
|
ignore_case | bool |
|
multiline | bool |
|
dot_all | bool |
|
unicode | bool |
|
sticky | bool |
|
impl(RegexFlags, ...)
default : (RegexFlags) fn() -> RegexFlagsEvery flag off — what Regex.new(pattern) (the one-argument form) uses,
and the base parse builds on.
Returns: RegexFlags
parse : (RegexFlags) fn(flags_str : String) -> Result(RegexFlags, RegexError)Parse a JavaScript-style flag string ("", "gi", "msy", …).
Returns .Err(RegexError.InvalidFlag(b)) on the first byte outside
gimsuy and .Err(RegexError.DuplicateFlag(b)) on the first repeat —
the first fault wins, so a caller sees one error, not a list. An empty
string is .Ok(default()).
The scan is BYTE-wise, which is correct here only because every legal flag is ASCII: a multi-byte rune in the flag string is reported as an invalid flag on its lead byte rather than as one character.
Parameters
| Name | Type | Notes |
|---|---|---|
flags_str | String |
Returns: Result(RegexFlags, RegexError)