basic_regex#
Synopsis#
real::basic_regex is the compiled pattern – the engine’s front door, with
a Python-re-shaped surface. Two aliases cover its storage policies:
real::regexcompiles at run time:real::regex re{pattern};.real::static_regexcarries the pattern in its type: parsed, compiled and exactly sized at compile time, matching allocates nothing and works inconstexpr– an invalid pattern is a compile error.
Lifetime and regions#
Group views borrow the subject: it must outlive the result. A temporary
std::stringis a compile error.find_iter/find_allare lvalue-only – a C++20 range-for would dangle on a temporary regex.match/search/fullmatchon a temporary regex returnowning_result_type; bind it withauto.pos/endposare byte offsets, not a slice.\Aand^(without multiline) still see the absolute position, so they fail whenpos > 0.
Interface#
-
template<typename Storage>
class basic_regex# A compiled regular expression, parameterized on its storage policy.
Storageowns 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:
Storage – real::detail::dynamic_storage or real::detail::static_storage.
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.
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 (orreal::match_result) does not compile, which is the point: there is no conversion that could drop the ownership and leave dangling views.On
static_regexthe two aliases are the same type: the tables have static storage duration, so a result from a temporary is already safe.
Public Functions
-
inline explicit constexpr basic_regex(std::string_view pattern, flags compile_flags = flags::none)#
Compiles
patternat run time (thereal::regexconstructor).- Parameters:
pattern – [in] The pattern text.
compile_flags – [in] Optional flags (merged with a leading global-flags group,
(?imsxaU)or(?flags-flags)).
- Throws:
real::regex_error – on an invalid or over-limit pattern.
-
constexpr basic_regex() = default#
Default constructor for the stateless compile-time storage (static_regex).
-
inline constexpr result_type match(std::string_view text) const &#
Match anchored at the start of
text(Pythonre.match).- Parameters:
text – [in] The subject text (must outlive the result).
- Returns:
The match result (test with
matched()/operatorbool).
-
inline constexpr result_type fullmatch(std::string_view text) const &#
Match the entire
text(Pythonre.fullmatch).- Parameters:
text – [in] The subject text (must outlive the result).
- Returns:
The match result.
-
inline constexpr result_type search(std::string_view text) const &#
Leftmost match anywhere in
text(Pythonre.search).- Parameters:
text – [in] The subject text (must outlive the result).
- Returns:
The match result.
-
inline constexpr result_type match(std::string_view text, std::size_t pos, std::size_t endpos = npos) const &#
Region-aware
match: anchored atposwithintext[0:endpos](Pythonre.matchwithpos/endpos). Byte offsets;posis not a slice (see run —\Afails atpos > 0);endposdefaults to the end oftext.- Parameters:
text – [in] Subject.
pos – [in] Byte offset the match must start at.
endpos – [in] Byte offset the region ends at; defaults to the end of
text.
- Returns:
The match result; falsy when the pattern does not match at
pos.
-
inline 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.- Parameters:
text – [in] Subject.
pos – [in] Byte offset the region starts at.
endpos – [in] Byte offset the region ends at; defaults to the end of
text.
- Returns:
The match result; falsy unless the whole region matches.
-
inline 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).- Parameters:
text – [in] Subject.
pos – [in] Byte offset the search starts at.
endpos – [in] Byte offset the region ends at; defaults to the end of
text.
- Returns:
The leftmost match in the region; falsy when there is none.
-
inline constexpr result_type match(const char *text) const &#
matchoverload for string literals.- Parameters:
text – [in] NUL-terminated text.
- Returns:
The result.
-
inline constexpr result_type fullmatch(const char *text) const &#
fullmatchoverload for string literals.- Parameters:
text – [in] NUL-terminated text.
- Returns:
The result.
-
inline constexpr result_type search(const char *text) const &#
searchoverload for string literals.- Parameters:
text – [in] NUL-terminated text.
- Returns:
The result.
-
inline constexpr owning_result_type match(std::string_view text) const &&#
matchon a temporary regex; the result owns its name context.- Parameters:
text – [in] The subject text (must outlive the result).
- Returns:
The match result.
-
inline constexpr owning_result_type fullmatch(std::string_view text) const &&#
fullmatchon a temporary regex; the result owns its name context.- Parameters:
text – [in] The subject text (must outlive the result).
- Returns:
The match result.
-
inline constexpr owning_result_type search(std::string_view text) const &&#
searchon a temporary regex; the result owns its name context.- Parameters:
text – [in] The subject text (must outlive the result).
- Returns:
The match result.
-
inline constexpr owning_result_type match(std::string_view text, std::size_t pos, std::size_t endpos = npos) const &&#
Region-aware
matchon a temporary regex; the result owns its name context.- Parameters:
text – [in] Subject.
pos – [in] Byte offset the match must start at.
endpos – [in] Byte offset the region ends at; defaults to the end of
text.
- Returns:
The match result.
-
inline constexpr owning_result_type fullmatch(std::string_view text, std::size_t pos, std::size_t endpos = npos) const &&#
Region-aware
fullmatchon a temporary regex; the result owns its name context.- Parameters:
text – [in] Subject.
pos – [in] Byte offset the region starts at.
endpos – [in] Byte offset the region ends at; defaults to the end of
text.
- Returns:
The match result.
-
inline constexpr owning_result_type search(std::string_view text, std::size_t pos, std::size_t endpos = npos) const &&#
Region-aware
searchon a temporary regex; the result owns its name context.- Parameters:
text – [in] Subject.
pos – [in] Byte offset the search starts at.
endpos – [in] Byte offset the region ends at; defaults to the end of
text.
- Returns:
The match result.
-
inline constexpr owning_result_type match(const char *text) const &&#
matchon a temporary regex, string-literal overload.- Parameters:
text – [in] NUL-terminated text.
- Returns:
The result.
-
inline constexpr owning_result_type fullmatch(const char *text) const &&#
fullmatchon a temporary regex, string-literal overload.- Parameters:
text – [in] NUL-terminated text.
- Returns:
The result.
-
inline constexpr owning_result_type search(const char *text) const &&#
searchon a temporary regex, string-literal overload.- Parameters:
text – [in] NUL-terminated text.
- Returns:
The result.
-
inline constexpr basic_match_range<Storage> find_iter(std::string_view text) const &#
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:
text – [in] The subject text (must outlive the range).
- Returns:
A basic_match_range usable directly in a range-for.
-
inline constexpr basic_match_range<Storage> find_iter(const char *text) const &#
find_iteroverload for string literals.- Parameters:
text – [in] NUL-terminated text.
- Returns:
The range.
-
inline 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)(Pythonfinditerwithpos/endpos).endpostruncates the subject to a view so iteration stops at it;posis the start, not a slice (see run). Byte offsets;endposdefaults to the end oftext.- Parameters:
text – [in] Subject.
pos – [in] Byte offset iteration starts at.
endpos – [in] Byte offset the region ends at; defaults to the end of
text.
- Returns:
A range over the matches in the region.
-
basic_match_range<Storage> find_iter(std::string_view text) const && = delete#
Deleted:
find_iteron a temporary regex would dangle.
-
basic_match_range<Storage> find_iter(const char *text) const && = delete#
Deleted:
find_iteron 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_iteron a temporary regex would dangle.
-
inline 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.
Prefer this over walking find_iter when only the count is needed. Region semantics match find_iter —
posis a start offset, not a slice (\\A/^still see the absolute position).- Parameters:
text – [in] The subject text.
pos – [in] Byte offset to begin counting from (0 = start of text).
endpos – [in] Exclusive end of the region; npos = end of text.
- Returns:
The number of non-overlapping matches in the region.
-
inline constexpr std::vector<result_type> find_all(std::string_view text) const &#
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:
text – [in] The subject text (must outlive the results).
- Returns:
A vector of match results.
-
inline constexpr std::vector<result_type> find_all(const char *text) const &#
find_alloverload for string literals.- Parameters:
text – [in] NUL-terminated text.
- Returns:
The results.
-
std::vector<result_type> find_all(std::string_view text) const && = delete#
Deleted:
find_allon a temporary regex would dangle.
-
std::vector<result_type> find_all(const char *text) const && = delete#
Deleted:
find_allon a temporary regex would dangle.
-
inline 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).The
replacementmay reference groups:$$→ ‘$’,$&or$0→ whole match,$1…, and${name}. This is not Pythonre.sub(\1/\g<name>) — that spelling is the Python and Go bindings. Returns an owning string, so a temporarytextis fine here.- Parameters:
text – [in] The subject text.
replacement – [in] The replacement template.
max_count – [in] Maximum replacements (0 = all).
- Throws:
real::regex_error – on a malformed group reference in
replacement.- Returns:
The resulting string.
-
inline constexpr std::vector<std::string_view> split(std::string_view text, std::size_t max_splits = 0) const#
Splits
texton matches (Pythonre.split).Each capturing group’s text is inserted after its split (an unset group yields an empty view, where Python would use
None).- Parameters:
text – [in] The subject text (must outlive the returned views).
max_splits – [in] Maximum splits (0 = split everywhere).
- Returns:
The pieces, with captured separators interleaved.
-
inline constexpr std::vector<std::string_view> split(const char *text, std::size_t max_splits = 0) const#
splitoverload for string literals.- Parameters:
text – [in] NUL-terminated text.
max_splits – [in] Max splits.
- Returns:
The pieces.
-
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_type> find_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.
-
inline constexpr std::string_view pattern() const#
Returns the pattern text this regex was compiled from.
- Returns:
The pattern, valid as long as this regex is alive.
-
inline constexpr flags compile_flags() const#
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.
-
inline constexpr std::size_t group_count() const#
Returns the number of capturing groups (excluding group 0).
- Returns:
The capturing-group count.
-
inline constexpr std::size_t group_index(std::string_view name) const#
Resolves a group name to its number.
- Parameters:
name – [in] The group name.
- Returns:
The group number, or real::npos if unknown.
-
inline constexpr std::vector<std::pair<std::string_view, std::size_t>> named_groups() const#
All named groups as (name, number) pairs, in declaration order.
- Returns:
The list of named groups.
The two aliases:
-
using real::regex = basic_regex<detail::dynamic_storage>#
The runtime-compiled regex type — the primary entry point.
-
template<fixed_string Pattern, flags F = flags::none>
using real::static_regex = basic_regex<detail::static_storage<Pattern, F>># A fully compile-time regex.
The pattern is parsed, compiled and exactly sized at compile time; matching allocates nothing and also works in a constexpr context. An invalid pattern is a compile error.
- Template Parameters:
Pattern – The pattern, as a fixed_string literal.
F – Compilation flags.
Two result aliases go with them, both derived from the type real::regex actually
returns rather than restated: real::match_result for an attempt on a live regex, which
borrows its name tables, and real::owning_match_result for an attempt on a temporary
one, which owns them.
Complexity#
Every matching call is guaranteed linear in the searched text – O(len(text)) – and never backtracks (ReDoS-safe by construction).
Allocation.
real::regexallocates when it compiles.static_regexdoes not.count_matchesallocates no result objects.replacereturns an owningstd::string.splitand group views borrow the subject.Sharing. A compiled regex is immutable and can be used from many threads. An iterator is not shared.
Example#
Compiled and run by the example-check gate on every push – tested code,
not an illustration:
// Runtime compilation -- real::regex is basic_regex over dynamic storage.
const real::regex counter {R"((\w+): (\d+))"};
if (const auto m = counter.search("retries: 12, errors: 3")) {
std::cout << m[1] << " = " << m[2] << "\n"; // retries = 12
}
for (const auto& m : counter.find_iter("retries: 12, errors: 3")) {
std::cout << m[0] << "\n"; // each "name: value" hit, left to right
}
// Compile-time compilation -- static_regex carries the pattern in its type:
// an invalid pattern is a compile error, and matching works in constexpr.
constexpr real::static_regex<R"((\w+)@(\w+))"> email;
static_assert(email.search("info@example.com")[2] == "example"sv);
See also#
The match object every call returns – groups, spans, truthiness: basic_match_result.
The lazy range
find_iterreturns: basic_match_range.Migrating from another engine: Drop-in.
The same surface from Python: Python API.
Multi-pattern which-matched: regex_set.