REAL
Regular Expression Algorithmic Library — constexpr C++20 regex
Loading...
Searching...
No Matches
real::basic_regex< Storage > Class Template Reference

A compiled regular expression, parameterized on its storage policy. More...

#include <real.hpp>

Public Types

using result_type = basic_match_result< typename Storage::slot_storage >
 This regex's match-result type.
 
using owning_result_type = basic_match_result< typename Storage::slot_storage, typename Storage::name_owner >
 What a single attempt on a temporary regex yields.
 

Public Member Functions

constexpr basic_regex (std::string_view pattern, flags compile_flags=flags::none)
 Compiles pattern at run time (the real::regex constructor).
 
constexpr basic_regex ()=default
 Default constructor for the stateless compile-time storage (static_regex).
 
constexpr result_type match (std::string_view text) const &
 Match anchored at the start of text (Python re.match).
 
constexpr result_type fullmatch (std::string_view text) const &
 Match the entire text (Python re.fullmatch).
 
constexpr result_type search (std::string_view text) const &
 Leftmost match anywhere in text (Python re.search).
 
constexpr result_type match (std::string_view text, std::size_t pos, std::size_t endpos=npos) const &
 Region-aware match: anchored at pos within text[0:endpos] (Python re.match with pos / endpos). Byte offsets; pos is not a slice (see run\A fails at pos > 0); endpos defaults to the end of text.
 
constexpr result_type fullmatch (std::string_view text, std::size_t pos, std::size_t endpos=npos) const &
 Region-aware fullmatch: the whole region [pos, endpos) must match.
 
constexpr result_type search (std::string_view text, std::size_t pos, std::size_t endpos=npos) const &
 Region-aware search: leftmost match within [pos, endpos).
 
constexpr result_type match (const char *text) const &
 match overload for string literals.
 
constexpr result_type fullmatch (const char *text) const &
 fullmatch overload for string literals.
 
constexpr result_type search (const char *text) const &
 search overload for string literals.
 
constexpr owning_result_type match (std::string_view text) const &&
 match on a temporary regex; the result owns its name context.
 
constexpr owning_result_type fullmatch (std::string_view text) const &&
 fullmatch on a temporary regex; the result owns its name context.
 
constexpr owning_result_type search (std::string_view text) const &&
 search on a temporary regex; the result owns its name context.
 
constexpr owning_result_type match (std::string_view text, std::size_t pos, std::size_t endpos=npos) const &&
 Region-aware match on a temporary regex; the result owns its name context.
 
constexpr owning_result_type fullmatch (std::string_view text, std::size_t pos, std::size_t endpos=npos) const &&
 Region-aware fullmatch on a temporary regex; the result owns its name context.
 
constexpr owning_result_type search (std::string_view text, std::size_t pos, std::size_t endpos=npos) const &&
 Region-aware search on a temporary regex; the result owns its name context.
 
constexpr owning_result_type match (const char *text) const &&
 match on a temporary regex, string-literal overload.
 
constexpr owning_result_type fullmatch (const char *text) const &&
 fullmatch on a temporary regex, string-literal overload.
 
constexpr owning_result_type search (const char *text) const &&
 search on a temporary regex, string-literal overload.
 
constexpr basic_match_range< Storage > find_iter (std::string_view text) const &
 Lazy range over all non-overlapping matches (Python re.finditer).
 
constexpr basic_match_range< Storage > find_iter (const char *text) const &
 find_iter overload for string literals.
 
constexpr basic_match_range< Storage > find_iter (std::string_view text, std::size_t pos, std::size_t endpos=npos) const &
 Region-aware find_iter: iterate matches within [pos, endpos) (Python finditer with pos / endpos). endpos truncates the subject to a view so iteration stops at it; pos is the start, not a slice (see run). Byte offsets; endpos defaults to the end of text.
 
constexpr basic_match_range< Storage > find_iter_longest (std::string_view text, std::size_t pos=0, std::size_t endpos=npos) const &
 Experimental leftmost-**longest** find_iter: iterate matches with POSIX (leftmost-longest) bounds rather than the default leftmost-first — the iterator twin of search_longest, sharing its prototype status. Region semantics match find_iterendpos truncates the subject to a view, pos is the start (not a slice). Byte offsets; captures are the winning thread's, not POSIX submatch. Every fast path is bypassed.
 
basic_match_range< Storage > find_iter_longest (std::string_view, std::size_t, std::size_t) const &&=delete
 Deleted: find_iter_longest on a temporary regex would dangle.
 
basic_match_range< Storage > find_iter (std::string_view text) const &&=delete
 Deleted: find_iter on a temporary regex would dangle.
 
basic_match_range< Storage > find_iter (const char *text) const &&=delete
 Deleted: find_iter on a temporary regex would dangle.
 
basic_match_range< Storage > find_iter (std::string_view text, std::size_t, std::size_t=npos) const &&=delete
 Deleted: region find_iter on a temporary regex would dangle.
 
constexpr std::size_t count_matches (std::string_view text, std::size_t pos=0, std::size_t endpos=npos) const
 Count non-overlapping matches without allocating result objects.
 
constexpr std::vector< result_typefind_all (std::string_view text) const &
 All matches, eagerly (like Python re.findall, but full results).
 
constexpr std::vector< result_typefind_all (const char *text) const &
 find_all overload for string literals.
 
std::vector< result_typefind_all (std::string_view text) const &&=delete
 Deleted: find_all on a temporary regex would dangle.
 
std::vector< result_typefind_all (const char *text) const &&=delete
 Deleted: find_all on a temporary regex would dangle.
 
constexpr std::string replace (std::string_view text, std::string_view replacement, std::size_t max_count=0) const
 Replaces matches in text (ECMAScript / std::regex_replace $1).
 
constexpr std::vector< std::string_view > split (std::string_view text, std::size_t max_splits=0) const
 Splits text on matches (Python re.split).
 
constexpr std::vector< std::string_view > split (const char *text, std::size_t max_splits=0) const
 split overload for string literals.
 
result_type match (const std::string &&text) const =delete
 Deleted: temporary text would dangle.
 
result_type fullmatch (const std::string &&text) const =delete
 Deleted: temporary text would dangle.
 
result_type search (const std::string &&text) const =delete
 Deleted: temporary text would dangle.
 
result_type match (const std::string &&text, std::size_t, std::size_t=npos) const =delete
 Deleted: temporary text would dangle.
 
result_type fullmatch (const std::string &&text, std::size_t, std::size_t=npos) const =delete
 Deleted: temporary text would dangle.
 
result_type search (const std::string &&text, std::size_t, std::size_t=npos) const =delete
 Deleted: temporary text would dangle.
 
basic_match_range< Storage > find_iter (const std::string &&text) const &=delete
 Deleted: temporary text would dangle.
 
basic_match_range< Storage > find_iter (const std::string &&text, std::size_t, std::size_t=npos) const &=delete
 Deleted: temporary text would dangle.
 
std::vector< result_typefind_all (const std::string &&text) const &=delete
 Deleted: temporary text would dangle.
 
std::vector< std::string_view > split (const std::string &&text, std::size_t max_splits=0) const =delete
 Deleted: temporary text would dangle.
 
constexpr std::string_view pattern () const
 Returns the pattern text this regex was compiled from.
 
constexpr flags compile_flags () const
 The flag set in force: constructor flags, plus a leading (?imsxa) group, minus its -removal.
 
constexpr std::size_t group_count () const
 Returns the number of capturing groups (excluding group 0).
 
constexpr detail::program_view raw_program () const
 The raw compiled program, for embedders (advanced).
 
constexpr bool has_first_byte_set () const noexcept
 Whether first-byte filtering is useful for this pattern.
 
constexpr std::optional< unsigned char > unique_first_byte () const noexcept
 The single byte every non-empty match must begin with, if unique.
 
constexpr bool may_start_with (unsigned char byte) const noexcept
 Whether a non-empty match can begin with byte (sound, conservative).
 
constexpr std::size_t group_index (std::string_view name) const
 Resolves a group name to its number.
 
constexpr std::vector< std::pair< std::string_view, std::size_t > > named_groups () const
 All named groups as (name, number) pairs, in declaration order.
 
constexpr std::size_t named_group_count () const
 How many named groups the pattern declares.
 
constexpr std::pair< std::string_view, std::size_t > named_group_at (std::size_t index) const
 The index-th named group, in declaration order.
 
result_type search_longest (std::string_view text) const
 EXPERIMENTAL, opt-in: a single leftmost-**longest** search (POSIX / RE2 set_longest_match), the default leftmost-first semantics left untouched. Among matches at the leftmost start it returns the longest; a lazy quantifier therefore behaves greedily, and captures are the leftmost-first thread's at that longest bound (not POSIX submatch). Runs on the general Pike loop (the first-match DFA / inner-literal fast paths are bypassed). A prototype for the match_semantics arc — not yet a stable API. Its iteration twin is find_iter_longest.
 
result_type search_longest (std::string_view text, std::size_t pos, std::size_t endpos=npos) const
 Region-aware form of search_longest — leftmost-longest search within [pos, endpos). pos is the start (not a slice, per run); endpos truncates the subject. Byte offsets.
 

Private Member Functions

constexpr std::size_t count_walk (std::string_view text, std::size_t pos, std::size_t endpos) const
 count_matches's walk: the ordinary one, run MATCHING-ONLY.
 
constexpr std::size_t count_trailing_la (std::string_view region, std::size_t pos) const
 count_matches over the trailing-lookaround walk, outlined.
 
constexpr std::string_view name_of (const detail::named_group &named_group) const
 Returns its name, sliced from the pattern text.
 
constexpr void expand_replacement (std::string &out, const result_type &match, std::string_view replacement) const
 Appends replacement to out, substituting group references.
 
constexpr result_type run (std::string_view text, detail::run_mode mode) const
 Runs a single match attempt from offset 0 (backs match/search/fullmatch).
 
constexpr result_type run (std::string_view text, std::size_t pos, std::size_t endpos, detail::run_mode mode, match_semantics sem=match_semantics::first) const
 Region-aware single attempt: match over text[0:endpos] starting at pos.
 

Static Private Member Functions

static constexpr owning_result_type detach (result_type result)
 Hands a result the name context it will need after this regex is gone.
 

Private Attributes

Storage program_
 The storage policy holding the compiled program.
 

Detailed Description

template<typename Storage>
class real::basic_regex< Storage >

A compiled regular expression, parameterized on its storage policy.

Storage owns the program; matching allocates only per-run scratch — and nothing at all when the storage is compile-time. Use the real::regex and real::static_regex aliases rather than this template directly.

Template Parameters
Storagereal::detail::dynamic_storage or real::detail::static_storage.

Member Typedef Documentation

◆ owning_result_type

template<typename Storage >
using real::basic_regex< Storage >::owning_result_type = basic_match_result<typename Storage::slot_storage, typename Storage::name_owner>

What a single attempt on a temporary regex yields.

Same spans and groups as result_type, plus ownership of the name tables the regex would otherwise lend. Bind it with auto. Spelling result_type (or real::match_result) does not compile, which is the point: there is no conversion that could drop the ownership and leave dangling views.

On static_regex the two aliases are the same type: the tables have static storage duration, so a result from a temporary is already safe.

Constructor & Destructor Documentation

◆ basic_regex()

template<typename Storage >
constexpr real::basic_regex< Storage >::basic_regex ( std::string_view  pattern,
flags  compile_flags = flags::none 
)
inlineexplicitconstexpr

Compiles pattern at run time (the real::regex constructor).

Parameters
[in]patternThe pattern text.
[in]compile_flagsOptional flags (merged with a leading global-flags group, (?imsxaU) or (?flags-flags)).
Exceptions
real::regex_erroron an invalid or over-limit pattern.

Member Function Documentation

◆ compile_flags()

template<typename Storage >
constexpr flags real::basic_regex< Storage >::compile_flags ( ) const
inlineconstexpr

The flag set in force: constructor flags, plus a leading (?imsxa) group, minus its -removal.

regex("(?-i)a", flags::icase) reports no flags::icase and matches case-sensitively — the accessor and the engine agree.

Returns
The effective flag set.

◆ count_matches()

template<typename Storage >
constexpr std::size_t real::basic_regex< Storage >::count_matches ( std::string_view  text,
std::size_t  pos = 0,
std::size_t  endpos = npos 
) const
inlineconstexpr

Count non-overlapping matches without allocating result objects.

Prefer this over walking find_iter when only the count is needed. Region semantics match find_iterpos is a start offset, not a slice (\\A / ^ still see the absolute position).

Parameters
[in]textThe subject text.
[in]posByte offset to begin counting from (0 = start of text).
[in]endposExclusive end of the region; npos = end of text.
Returns
The number of non-overlapping matches in the region.

◆ count_trailing_la()

template<typename Storage >
constexpr std::size_t real::basic_regex< Storage >::count_trailing_la ( std::string_view  region,
std::size_t  pos 
) const
inlineconstexprprivate

count_matches over the trailing-lookaround walk, outlined.

OUTLINED AND COLD for the same reason basic_match_iterator::decide_batching is: this branch is taken only when pattern_hints::trailing_lookaround is armed, yet inline it put a SECOND fully inlined walk inside count_matches – the function every throughput measurement runs. That made count_matches large enough to sit on a codegen cliff: adding a single branch to the batched dispatch (no new function body, eligibility already outlined) recompiled it from 610 to 606 instructions, and the campaign that measured that state charged single [a-z] +10.7 %, \b\w+\b +4.0 %, \w+ +3.7 %, \w{2,} +3.2 % and fields [^,]+ +2.8 %, all above their own floors at 24 of 24 draws, on rows whose own code was byte-identical. The toll was not the change – it was this function being re-decided.

Parameters
[in]regionThe already-clamped subject.
[in]posWhere the walk starts.
Returns
The match count.

◆ count_walk()

template<typename Storage >
constexpr std::size_t real::basic_regex< Storage >::count_walk ( std::string_view  text,
std::size_t  pos,
std::size_t  endpos 
) const
inlineconstexprprivate

count_matches's walk: the ordinary one, run MATCHING-ONLY.

OUTLINED FIRST, AT ZERO BEHAVIOUR, AND JUDGED BEFORE ANYTHING WAS PUT IN IT. Adding a single branch to count_matches once recompiled it from 610 to 606 instructions and charged single [a-z] +10.7 %, \b\w+\b +4.0 %, \w+ +3.7 % and fields [^,]+ +2.8 %, all above their floors at 24 of 24 draws, on rows whose own code was byte-identical: the toll was that function being re-decided, not the branch. So the container went in alone and measured flat over 26 rows (medians -0.3 % to +0.8 %, 0 rows REAL) before this policy was added, which is why the policy needs no branch in count_matches at all.

THE POLICY. This function returns a NUMBER: no caller can observe a capture group, so writing them is pure loss. The walk therefore runs on a private copy of the program whose detail::pattern_hints::capture_free_walk is set — the same walk (?:...)-only patterns already get, where a thread's whole capture state is group 0's start in one scalar and the refcounted COW pool is never touched. On a capture-heavy pattern that takes the general VM, the increfs and copy-on-writes drop to ZERO while the VM steps exactly the same positions. That last part is the point — the walk is identical, only its bookkeeping is gone.

ONE FIELD, DELIBERATELY. slot_count is left alone even though the walk now fills only two slots: the batched span routes arm on slot_count == 2, so lowering it would ROUTE the pattern somewhere else and the measurement would be of a different engine. The same trap in reverse is what made the census's headline finding an illusion: (?:foo|bar)+baz is far cheaper than (foo|bar)+baz, but the second is a different PROGRAM taking a different route, and its VM steps an order of magnitude fewer positions. No walk flag can produce that; rewriting a user's groups to non-capturing at compile time might, and is a separate question with its own answers to give.

The structural condition is still asked (detail::capture_free_walk_structural) rather than assumed: it is a property of the program, and a program whose save 0 can be skipped would give a wrong answer, not a slow one. What this drops is the other half of the compiler's guard — no save past slot 1, and slot_count == 2 — which exists to protect captures nobody here is going to read.

THE FLAG IS SET BY THE RANGE, NOT HERE, and that is a measured requirement rather than a preference. Mutating a local view and handing it over costs a SECOND copy of a program_view, a fixed per-call cost with no proportional work behind it – flat in the subject length. The canonical rows never saw it: they measure this surface as THROUGHPUT on multi-kilobyte subjects, where one fixed copy amortises under the noise floor. Passing the intent instead of a mutated view leaves exactly find_iter's one copy.

noinline but NOT cold, unlike count_trailing_la – that branch is taken only when a hint is armed, this one is the ordinary path.

Parameters
[in]textThe subject.
[in]posWhere the walk starts.
[in]endposRegion end, as find_iter takes it.
Returns
The match count.

◆ detach()

template<typename Storage >
static constexpr owning_result_type real::basic_regex< Storage >::detach ( result_type  result)
inlinestaticconstexprprivate

Hands a result the name context it will need after this regex is gone.

Taken and returned by value so the prvalue from run is constructed straight into the parameter and named-returned out: the rvalue overloads pay no move for going through here.

Parameters
[in]resultThe freshly run result.
Returns
The same result, no longer borrowing from this regex.

◆ expand_replacement()

template<typename Storage >
constexpr void real::basic_regex< Storage >::expand_replacement ( std::string &  out,
const result_type match,
std::string_view  replacement 
) const
inlineconstexprprivate

Appends replacement to out, substituting group references.

An invalid or out-of-range reference is an error (Python's rule), not left in place. The template spelling is ECMAScript / std::regex: $1, not \1.

Parameters
[in,out]outThe output string to append to.
[in]matchThe match supplying the captured groups.
[in]replacementThe replacement template ($$, $&, $1, ${name}).
Exceptions
real::regex_erroron a malformed or out-of-range reference.

◆ find_all() [1/2]

template<typename Storage >
constexpr std::vector< result_type > real::basic_regex< Storage >::find_all ( const char *  text) const &
inlineconstexpr

find_all overload for string literals.

Parameters
[in]textNUL-terminated text.
Returns
The results.

◆ find_all() [2/2]

template<typename Storage >
constexpr std::vector< result_type > real::basic_regex< Storage >::find_all ( std::string_view  text) const &
inlineconstexpr

All matches, eagerly (like Python re.findall, but full results).

Lvalue-only, same reason as find_iter. High match counts allocate one result per hit; prefer count_matches when only the number matters, and find_iter when you can stream.

Parameters
[in]textThe subject text (must outlive the results).
Returns
A vector of match results.

◆ find_iter() [1/3]

template<typename Storage >
constexpr basic_match_range< Storage > real::basic_regex< Storage >::find_iter ( const char *  text) const &
inlineconstexpr

find_iter overload for string literals.

Parameters
[in]textNUL-terminated text.
Returns
The range.

◆ find_iter() [2/3]

template<typename Storage >
constexpr basic_match_range< Storage > real::basic_regex< Storage >::find_iter ( std::string_view  text) const &
inlineconstexpr

Lazy range over all non-overlapping matches (Python re.finditer).

Only callable on an lvalue regex: a C++20 range-for would dangle if the regex were a temporary (the range initializer dies before the loop body), so the rvalue overloads are deleted.

Parameters
[in]textThe subject text (must outlive the range).
Returns
A basic_match_range usable directly in a range-for.

◆ find_iter() [3/3]

template<typename Storage >
constexpr basic_match_range< Storage > real::basic_regex< Storage >::find_iter ( std::string_view  text,
std::size_t  pos,
std::size_t  endpos = npos 
) const &
inlineconstexpr

Region-aware find_iter: iterate matches within [pos, endpos) (Python finditer with pos / endpos). endpos truncates the subject to a view so iteration stops at it; pos is the start, not a slice (see run). Byte offsets; endpos defaults to the end of text.

Parameters
[in]textSubject.
[in]posByte offset iteration starts at.
[in]endposByte offset the region ends at; defaults to the end of text.
Returns
A range over the matches in the region.

◆ find_iter_longest()

template<typename Storage >
constexpr basic_match_range< Storage > real::basic_regex< Storage >::find_iter_longest ( std::string_view  text,
std::size_t  pos = 0,
std::size_t  endpos = npos 
) const &
inlineconstexpr

Experimental leftmost-**longest** find_iter: iterate matches with POSIX (leftmost-longest) bounds rather than the default leftmost-first — the iterator twin of search_longest, sharing its prototype status. Region semantics match find_iterendpos truncates the subject to a view, pos is the start (not a slice). Byte offsets; captures are the winning thread's, not POSIX submatch. Every fast path is bypassed.

Parameters
[in]textSubject.
[in]posByte offset iteration starts at.
[in]endposByte offset the region ends at; defaults to the end of text.
Returns
A range over the leftmost-longest matches in the region.

◆ fullmatch() [1/6]

template<typename Storage >
constexpr result_type real::basic_regex< Storage >::fullmatch ( const char *  text) const &
inlineconstexpr

fullmatch overload for string literals.

Parameters
[in]textNUL-terminated text.
Returns
The result.

◆ fullmatch() [2/6]

template<typename Storage >
constexpr owning_result_type real::basic_regex< Storage >::fullmatch ( const char *  text) const &&
inlineconstexpr

fullmatch on a temporary regex, string-literal overload.

Parameters
[in]textNUL-terminated text.
Returns
The result.

◆ fullmatch() [3/6]

template<typename Storage >
constexpr result_type real::basic_regex< Storage >::fullmatch ( std::string_view  text) const &
inlineconstexpr

Match the entire text (Python re.fullmatch).

Parameters
[in]textThe subject text (must outlive the result).
Returns
The match result.

◆ fullmatch() [4/6]

template<typename Storage >
constexpr owning_result_type real::basic_regex< Storage >::fullmatch ( std::string_view  text) const &&
inlineconstexpr

fullmatch on a temporary regex; the result owns its name context.

Parameters
[in]textThe subject text (must outlive the result).
Returns
The match result.

◆ fullmatch() [5/6]

template<typename Storage >
constexpr result_type real::basic_regex< Storage >::fullmatch ( std::string_view  text,
std::size_t  pos,
std::size_t  endpos = npos 
) const &
inlineconstexpr

Region-aware fullmatch: the whole region [pos, endpos) must match.

Parameters
[in]textSubject.
[in]posByte offset the region starts at.
[in]endposByte offset the region ends at; defaults to the end of text.
Returns
The match result; falsy unless the whole region matches.

◆ fullmatch() [6/6]

template<typename Storage >
constexpr owning_result_type real::basic_regex< Storage >::fullmatch ( std::string_view  text,
std::size_t  pos,
std::size_t  endpos = npos 
) const &&
inlineconstexpr

Region-aware fullmatch on a temporary regex; the result owns its name context.

Parameters
[in]textSubject.
[in]posByte offset the region starts at.
[in]endposByte offset the region ends at; defaults to the end of text.
Returns
The match result.

◆ group_count()

template<typename Storage >
constexpr std::size_t real::basic_regex< Storage >::group_count ( ) const
inlineconstexpr

Returns the number of capturing groups (excluding group 0).

Returns
The capturing-group count.

◆ group_index()

template<typename Storage >
constexpr std::size_t real::basic_regex< Storage >::group_index ( std::string_view  name) const
inlineconstexpr

Resolves a group name to its number.

Parameters
[in]nameThe group name.
Returns
The group number, or real::npos if unknown.

◆ has_first_byte_set()

template<typename Storage >
constexpr bool real::basic_regex< Storage >::has_first_byte_set ( ) const
inlineconstexprnoexcept

Whether first-byte filtering is useful for this pattern.

true iff every non-empty match provably begins with a byte from a known set, so may_start_with can reject positions. false when a zero-length match is possible (or the set is empty) — then may_start_with is true for every byte and the filter buys nothing. This is the same set the engine's own prefilter uses, exposed for embedders (e.g. a lexer's rule dispatch).

Returns
true if the first-byte set is usable.

◆ match() [1/6]

template<typename Storage >
constexpr result_type real::basic_regex< Storage >::match ( const char *  text) const &
inlineconstexpr

match overload for string literals.

Parameters
[in]textNUL-terminated text.
Returns
The result.

◆ match() [2/6]

template<typename Storage >
constexpr owning_result_type real::basic_regex< Storage >::match ( const char *  text) const &&
inlineconstexpr

match on a temporary regex, string-literal overload.

Parameters
[in]textNUL-terminated text.
Returns
The result.

◆ match() [3/6]

template<typename Storage >
constexpr result_type real::basic_regex< Storage >::match ( std::string_view  text) const &
inlineconstexpr

Match anchored at the start of text (Python re.match).

Parameters
[in]textThe subject text (must outlive the result).
Returns
The match result (test with matched() / operator bool).

◆ match() [4/6]

template<typename Storage >
constexpr owning_result_type real::basic_regex< Storage >::match ( std::string_view  text) const &&
inlineconstexpr

match on a temporary regex; the result owns its name context.

Parameters
[in]textThe subject text (must outlive the result).
Returns
The match result.

◆ match() [5/6]

template<typename Storage >
constexpr result_type real::basic_regex< Storage >::match ( std::string_view  text,
std::size_t  pos,
std::size_t  endpos = npos 
) const &
inlineconstexpr

Region-aware match: anchored at pos within text[0:endpos] (Python re.match with pos / endpos). Byte offsets; pos is not a slice (see run\A fails at pos > 0); endpos defaults to the end of text.

Parameters
[in]textSubject.
[in]posByte offset the match must start at.
[in]endposByte offset the region ends at; defaults to the end of text.
Returns
The match result; falsy when the pattern does not match at pos.

◆ match() [6/6]

template<typename Storage >
constexpr owning_result_type real::basic_regex< Storage >::match ( std::string_view  text,
std::size_t  pos,
std::size_t  endpos = npos 
) const &&
inlineconstexpr

Region-aware match on a temporary regex; the result owns its name context.

Parameters
[in]textSubject.
[in]posByte offset the match must start at.
[in]endposByte offset the region ends at; defaults to the end of text.
Returns
The match result.

◆ may_start_with()

template<typename Storage >
constexpr bool real::basic_regex< Storage >::may_start_with ( unsigned char  byte) const
inlineconstexprnoexcept

Whether a non-empty match can begin with byte (sound, conservative).

A false result is a guarantee: no non-empty match of this pattern begins with byte. A true result is a conservative superset — it does not promise a match actually starts there. When first-byte filtering is not usable (has_first_byte_set is false, i.e. an empty match is possible), this returns true for every byte, so it is safe to use on its own.

Parameters
[in]byteThe candidate leading byte.
Returns
false only when byte can never start a non-empty match.

◆ name_of()

template<typename Storage >
constexpr std::string_view real::basic_regex< Storage >::name_of ( const detail::named_group named_group) const
inlineconstexprprivate

Returns its name, sliced from the pattern text.

Parameters
[in]named_groupA named group.
Returns
Its name, sliced from the pattern text.

◆ named_group_at()

template<typename Storage >
constexpr std::pair< std::string_view, std::size_t > real::basic_regex< Storage >::named_group_at ( std::size_t  index) const
inlineconstexpr

The index-th named group, in declaration order.

Parameters
[in]indexPosition in [0, named_group_count()); out of range is undefined, as for any indexed accessor on this class.
Returns
Its name (a view into the pattern text) and its capture-group number.

◆ named_group_count()

template<typename Storage >
constexpr std::size_t real::basic_regex< Storage >::named_group_count ( ) const
inlineconstexpr

How many named groups the pattern declares.

With named_group_at, this is the allocation-free way to enumerate them. named_groups materialises a vector on every call, so a caller walking the names one at a time — which is what a name-by-number ABI does — paid a fresh vector per name. Reading the program's own span instead removes the allocation entirely, a constant factor that grows with the name count.

Note
It is a constant factor and not a complexity fix, which is worth being precise about: resolving N names through an interface keyed by group NUMBER is N scans of N either way. Making that linear needs an index-keyed entry point at the ABI, not a cheaper accessor here.
Returns
The number of named groups.

◆ named_groups()

template<typename Storage >
constexpr std::vector< std::pair< std::string_view, std::size_t > > real::basic_regex< Storage >::named_groups ( ) const
inlineconstexpr

All named groups as (name, number) pairs, in declaration order.

Returns
The list of named groups.

◆ pattern()

template<typename Storage >
constexpr std::string_view real::basic_regex< Storage >::pattern ( ) const
inlineconstexpr

Returns the pattern text this regex was compiled from.

Returns
The pattern, valid as long as this regex is alive.

◆ raw_program()

template<typename Storage >
constexpr detail::program_view real::basic_regex< Storage >::raw_program ( ) const
inlineconstexpr

The raw compiled program, for embedders (advanced).

Lets an embedder (e.g. the Python binding) drive detail::pike_vm with caller-owned reusable scratch. Valid as long as this regex is alive.

Returns
A non-owning detail::program_view.

◆ replace()

template<typename Storage >
constexpr std::string real::basic_regex< Storage >::replace ( std::string_view  text,
std::string_view  replacement,
std::size_t  max_count = 0 
) const
inlineconstexpr

Replaces matches in text (ECMAScript / std::regex_replace $1).

The replacement may reference groups: $$ → '$', $& or $0 → whole match, $1 …, and ${name}. This is not Python re.sub (\1 / \g<name>) — that spelling is the Python and Go bindings. Returns an owning string, so a temporary text is fine here.

Parameters
[in]textThe subject text.
[in]replacementThe replacement template.
[in]max_countMaximum replacements (0 = all).
Returns
The resulting string.
Exceptions
real::regex_erroron a malformed group reference in replacement.

◆ run() [1/2]

template<typename Storage >
constexpr result_type real::basic_regex< Storage >::run ( std::string_view  text,
detail::run_mode  mode 
) const
inlineconstexprprivate

Runs a single match attempt from offset 0 (backs match/search/fullmatch).

Parameters
[in]textThe subject text.
[in]modeThe anchoring mode.
Returns
The match result.

◆ run() [2/2]

template<typename Storage >
constexpr result_type real::basic_regex< Storage >::run ( std::string_view  text,
std::size_t  pos,
std::size_t  endpos,
detail::run_mode  mode,
match_semantics  sem = match_semantics::first 
) const
inlineconstexprprivate

Region-aware single attempt: match over text[0:endpos] starting at pos.

pos is the VM start offset, not a slice — zero-width assertions still see the absolute position, so \A and ^ (non-multiline) fail at pos > 0, matching Python re. endpos truncates the subject to a view (no copy), so $ / \Z treat it as the end. endpos is clamped to the text length; pos > endpos yields no match. Capture offsets are absolute byte offsets in text.

Parameters
[in]textThe full subject (offsets are relative to it; must outlive the result).
[in]posByte offset to start matching at.
[in]endposByte offset of the exclusive region end; npos = end of text.
[in]modeThe anchoring mode.
[in]semMatch semantics: leftmost-first (default) or the experimental leftmost-longest.
Returns
The match result, with offsets absolute in text.

◆ search() [1/6]

template<typename Storage >
constexpr result_type real::basic_regex< Storage >::search ( const char *  text) const &
inlineconstexpr

search overload for string literals.

Parameters
[in]textNUL-terminated text.
Returns
The result.

◆ search() [2/6]

template<typename Storage >
constexpr owning_result_type real::basic_regex< Storage >::search ( const char *  text) const &&
inlineconstexpr

search on a temporary regex, string-literal overload.

Parameters
[in]textNUL-terminated text.
Returns
The result.

◆ search() [3/6]

template<typename Storage >
constexpr result_type real::basic_regex< Storage >::search ( std::string_view  text) const &
inlineconstexpr

Leftmost match anywhere in text (Python re.search).

Parameters
[in]textThe subject text (must outlive the result).
Returns
The match result.

◆ search() [4/6]

template<typename Storage >
constexpr owning_result_type real::basic_regex< Storage >::search ( std::string_view  text) const &&
inlineconstexpr

search on a temporary regex; the result owns its name context.

Parameters
[in]textThe subject text (must outlive the result).
Returns
The match result.

◆ search() [5/6]

template<typename Storage >
constexpr result_type real::basic_regex< Storage >::search ( std::string_view  text,
std::size_t  pos,
std::size_t  endpos = npos 
) const &
inlineconstexpr

Region-aware search: leftmost match within [pos, endpos).

Parameters
[in]textSubject.
[in]posByte offset the search starts at.
[in]endposByte offset the region ends at; defaults to the end of text.
Returns
The leftmost match in the region; falsy when there is none.

◆ search() [6/6]

template<typename Storage >
constexpr owning_result_type real::basic_regex< Storage >::search ( std::string_view  text,
std::size_t  pos,
std::size_t  endpos = npos 
) const &&
inlineconstexpr

Region-aware search on a temporary regex; the result owns its name context.

Parameters
[in]textSubject.
[in]posByte offset the search starts at.
[in]endposByte offset the region ends at; defaults to the end of text.
Returns
The match result.

◆ search_longest() [1/2]

template<typename Storage >
result_type real::basic_regex< Storage >::search_longest ( std::string_view  text) const
inline

EXPERIMENTAL, opt-in: a single leftmost-**longest** search (POSIX / RE2 set_longest_match), the default leftmost-first semantics left untouched. Among matches at the leftmost start it returns the longest; a lazy quantifier therefore behaves greedily, and captures are the leftmost-first thread's at that longest bound (not POSIX submatch). Runs on the general Pike loop (the first-match DFA / inner-literal fast paths are bypassed). A prototype for the match_semantics arc — not yet a stable API. Its iteration twin is find_iter_longest.

Parameters
[in]textSubject.
Returns
The leftmost-longest match; falsy when there is none.

◆ search_longest() [2/2]

template<typename Storage >
result_type real::basic_regex< Storage >::search_longest ( std::string_view  text,
std::size_t  pos,
std::size_t  endpos = npos 
) const
inline

Region-aware form of search_longest — leftmost-longest search within [pos, endpos). pos is the start (not a slice, per run); endpos truncates the subject. Byte offsets.

Parameters
[in]textSubject.
[in]posByte offset the search starts at.
[in]endposByte offset the region ends at; defaults to the end of text.
Returns
The leftmost-longest match in the region; falsy when there is none.

◆ split() [1/2]

template<typename Storage >
constexpr std::vector< std::string_view > real::basic_regex< Storage >::split ( const char *  text,
std::size_t  max_splits = 0 
) const
inlineconstexpr

split overload for string literals.

Parameters
[in]textNUL-terminated text.
[in]max_splitsMax splits.
Returns
The pieces.

◆ split() [2/2]

template<typename Storage >
constexpr std::vector< std::string_view > real::basic_regex< Storage >::split ( std::string_view  text,
std::size_t  max_splits = 0 
) const
inlineconstexpr

Splits text on matches (Python re.split).

Each capturing group's text is inserted after its split (an unset group yields an empty view, where Python would use None).

Parameters
[in]textThe subject text (must outlive the returned views).
[in]max_splitsMaximum splits (0 = split everywhere).
Returns
The pieces, with captured separators interleaved.

◆ unique_first_byte()

template<typename Storage >
constexpr std::optional< unsigned char > real::basic_regex< Storage >::unique_first_byte ( ) const
inlineconstexprnoexcept

The single byte every non-empty match must begin with, if unique.

Returns
The byte when the pattern has exactly one possible first byte (e.g. a plain literal like if / def); std::nullopt for zero or several.

The documentation for this class was generated from the following file: