Regular Expressionsο
The Regular Expression Interfaceο
Creating an Expressionο
RegEx::compile accepts owning UTF-8, UTF-16 and UTF-32 Core strings.
Every overload returns RegExPtr and produces equivalent compiled behaviour.
using namespace erbsland::text::literals;
const auto expression8 = re::RegEx::compile("(A)(π)(B)"_el);
const auto expression16 = re::RegEx::compile(text::U16String{u"(A)(π)(B)"_el});
const auto expression32 = re::RegEx::compile(text::U32String{U"(A)(π)(B)"_el});
Invalid syntax and configured limits throw RegExError.
Pattern length is measured in decoded code points, independently of the source encoding.
The compiled object retains the normalized UTF-8 source text returned by
pattern().
UTF-16 and UTF-32 patterns therefore produce the same stored representation as an equivalent UTF-8 pattern.
Lazy Compilationο
RegEx::lazyCompile retains the pattern, flags and settings without parsing the pattern immediately.
The first matching, replacement or diagnostic operation compiles the engine.
Copies of a lazy expression share this state, and concurrent first use compiles one engine for all copies.
Use isCompiled() to inspect the state without triggering compilation.
Use compileNow() when an application needs to validate a lazy pattern before matching.
Invalid lazy patterns throw RegExError at that point.
A failed attempt leaves the expression uncompiled, and a later operation retries compilation.
Matching Operationsο
Each supported string width provides the same five operations:
matchstarts at the beginning of the subject.fullMatchrequires the complete subject to match.findFirstsearches for the first match.findAlllazily yields matches from a coroutine generator.collectAlleagerly returns all matches in astd::vector.
match, fullMatch and findFirst return nullptr when no match exists.
The generator and list operations return an empty result.
Subjects and Resultsο
The subject parameter determines the result family:
text::StringreturnsMatch.text::U16StringreturnsMatch16.text::U32StringreturnsMatch32.
Core strings own their backing storage. Inputs, returned matches and lazy generators therefore remain valid after the callerβs original string or temporary has been destroyed.
Tolerant String Decodingο
All Core-string entry points decode malformed source units as U+FFFD. This applies to patterns, UTF-8/16/32 subjects, assembler source and replacement expressions. Replacement characters participate in parsing and matching like any other character, including CRLF lookahead and zero-width advancement paths.
Custom input implementations control their own decoding policy and may throw encoding or other runtime errors. Such exceptions propagate unchanged.
Text Streamsο
The matching operations also accept stream::TextInputStreamPtr.
The stream must support positioning because the matching engine stores only byte ranges for capture groups.
After a successful match, the API seeks to each captured range and copies its text into the returned
Match object. The returned match therefore remains valid after the stream has been
reused or destroyed.
Capture copying restores the streamβs logical position before the next matching operation continues.
Streams that do not support positioning cause err::ParameterError.
Read or positioning timeouts cause stream::StreamError and are never
treated as end-of-input.
Null Charactersο
By default, regular expression patterns reject U+0000, including raw pattern text and character escapes.
Enable
Feature::AcceptNullInPattern only when a pattern needs
to match a null character.
Matching input accepts U+0000 by default and processes all following input normally.
To reject U+0000 at the point it is read, disable
Feature::AcceptNullInInput; matching then throws
text::EncodingError.
Replacementο
replaceAll accepts either a replacement expression or a callback receiving
MatchPtr. The callback returns an owning
text::String, allowing it to reuse unchanged input or match content
without creating an intermediate string copy.
Use text::U8String::toEscaped with
text::EscapeFormat::RegEx to escape text for insertion as a
literal pattern.
Settingsο
The Settings class allows you to control which features are accepted and which
limits apply when compiling and executing regular expressions.
Settings are applied during compilation and define the behaviour of the resulting
RegEx instance.
They are especially important when your application processes patterns from external or untrusted sources, such as user
configuration files or plug-in systems.
Limiting the Run-Timeο
When working with externally provided patterns, it is strongly recommended to limit the maximum run-time of matching operations.
Using setTimeout, you can define a per-call time limit for all matching
operations performed by a
RegEx instance.
If a matching operation exceeds the configured timeout, it is aborted and an
RegExError exception with the error category
Timeout is thrown.
This mechanism protects your application against excessively complex patterns or pathological input that would otherwise lead to long or unbounded execution times.
Setting Pattern Complexity Limitsο
In addition to time limits, the library provides a set of limits that restrict individual aspects of pattern complexity, such as nesting depth, repetition counts, or internal resource usage.
These limits can only be tightened, never extended. The library ships with a carefully chosen set of safe default limits that work well for most use cases.
Reducing these limits is useful when you want to:
Prevent excessive memory consumption
Guard against denial-of-service scenarios
Enforce predictable performance characteristics
All limits are checked during compilation or execution and result in a well-defined error if exceeded.
Enabling or Disabling Featuresο
By default, the regular expression support in Erbsland Core enables a number of compatibility features to ease migration from existing regular expression engines.
While convenient, some of these features come with ambiguities, surprising edge cases, or performance costs. For applications that accept patterns from external sources, it is often desirable to restrict the accepted syntax more strictly.
The feature flags in Settings allow you to explicitly control which parts of the
pattern syntax are enabled.
A sensible starting point for untrusted patterns is disabling AllCompatibility, thereby accepting only the core,
well-defined syntax.
Certain particularly problematic features are disabled by default:
EmptyAlternativesEmptyGroups
Both can lead to unintuitive matches and make patterns harder to reason about. If you enable them, you should do so consciously and only when their behaviour is clearly understood and required.
Choosing the Right Settingsο
For internal, fully controlled patterns, the default settings are usually sufficient and provide maximum convenience.
For externally supplied patterns, we recommend:
Enabling a strict timeout
Tightening complexity limits where possible
Disabling compatibility features that are not explicitly required
This layered approach keeps your application robust while still allowing powerful and expressive regular expressions.
The Input Interfaceο
The Input interface allows you to provide custom input sources to the regular
expression engine.
Because the regular expression engine in Erbsland Core is based on a Thompson NFA, input is consumed sequentially and processed in a highly efficient streaming fashion. This makes it possible to match patterns not only against built-in Core strings, but also against custom iterators or application-specific sources.
The input interface is a low-level extension point intended for advanced use cases. If you only need to match against strings, the built-in string overloads are usually the better and simpler choice. They also provide a defined tolerant decoding policy: malformed units are replaced with U+FFFD.
How to Implement Your Sourceο
To implement a custom input source, derive from one of the following classes:
The chosen base class determines which unified match family is returned: Match, Match16 or Match32.
A custom input implements createMatch and decides whether captured content is copied or retained as a slice of its
source.
Your implementation must override the abstract methods defined by
InputBase. These methods form the
contract between your input source and the matching engine.
Implementation Requirementsο
The most important method is
read. It is invoked in the hot loop
of the matching engine and must therefore be implemented as efficiently as possible.
When implementing an input source, the following rules must be respected:
readmust return the next character astext::Chartogether with its position. Every returned character must be a valid Unicode scalar value.When the end of the input is reached,
text::Char::endOfDatamust be returned.Repeated calls to
readafter the end of the input must continue to succeed and keep returning the end-of-data signal.Reserved
text::Charsignals other than the end-of-data signal, surrogate code points and values above U+10FFFF must never be returned.The returned position must advance monotonically and must uniquely identify the character within the input stream.
If line-break folding (CRLF handling) is enabled for the regular expression, your input source must additionally implement:
peekto look ahead without consuming inputskipto advance by aunit::CpLength
These methods allow the engine to treat CRLF sequences as a single logical line break while preserving correct
positional information.
The matching engine relies on this contract and does not repeat Unicode validity checks in its hot loop.
Validate or decode custom data before returning it.
Error-tolerant inputs should replace invalid source values with
text::Char::replacement.
Incorrect or incomplete implementations may lead to incorrect matches or undefined behavior.
Exception Propagationο
A custom input may choose strict decoding and throw a Core encoding error.
Exceptions thrown by read(), peek(), skip() or createMatch() propagate unchanged through every matching
operation.
The engine does not replace, wrap or translate these exceptions into RegExError.
Example Implementationο
The following example shows a complete implementation of a custom input source that reads characters from a
std::vector.
While simplified, it demonstrates all required methods and lifetime rules.
The example treats the vector as an error-tolerant source and replaces invalid UTF-32 values while reading and capturing
its content.
1#pragma once
2
3#include <erbsland/Char.hpp>
4#include <erbsland/re/Input.hpp>
5#include <erbsland/re/Match.hpp>
6#include <erbsland/text/u32/U32String.hpp>
7
8#include <string>
9#include <utility>
10#include <vector>
11
12// FIXME!
13// This should be moved into a demo - to make sure it compiles and works as expected.
14// This demo also makes no sense with Erbsland Core, it needs to adapted to use the correct types.
15
16class VectorMatch : public erbsland::re::Match32 {
17public:
18 using Match32::Match32;
19
20public:
21 VectorMatch(el::re::CaptureGroupList captureGroupList, std::u32string &&capturedContent, const std::size_t offset) :
22 Match32(std::move(captureGroupList)), _capturedContent{std::move(capturedContent)}, _offset{offset} {}
23 ~VectorMatch() override = default;
24
25protected:
26 [[nodiscard]] auto getContentForGroup(const el::re::CaptureGroup &group) const noexcept
27 -> el::text::U32String override {
28
29 return el::text::U32StringEditor{_capturedContent}.slice({group.begin() - _offset, group.size()});
30 }
31
32private:
33 std::u32string _capturedContent;
34 std::size_t _offset;
35};
36
37class VectorInput : public erbsland::re::Input32 {
38public:
39 explicit VectorInput(const std::vector<char32_t> &textVector) : _vectorRef(textVector) {}
40 ~VectorInput() override = default;
41
42public:
43 [[nodiscard]] auto read() -> el::re::CharAndPosition override {
44 if (_position >= _vectorRef.size()) {
45 return {el::text::Char::endOfData(), _position};
46 }
47 const auto position = _position;
48 const auto character = decodeCodePoint(_vectorRef[position]);
49 _position += 1;
50 return {character, position};
51 }
52 [[nodiscard]] auto peek() -> el::re::CharAndPosition override {
53 if (_position >= _vectorRef.size()) {
54 return {el::text::Char::endOfData(), _position};
55 }
56 return {decodeCodePoint(_vectorRef[_position]), _position};
57 }
58 void skip(const std::size_t characterCount) override {
59 _position += characterCount;
60 if (_position > _vectorRef.size()) {
61 _position = _vectorRef.size();
62 }
63 }
64 [[nodiscard]] auto createMatch(el::re::CaptureGroupList captureGroupList) -> el::re::Match32Ptr override {
65
66 std::u32string capturedContent;
67 const std::size_t offset = captureGroupList.front().begin();
68 const std::size_t end = captureGroupList.front().end();
69 for (std::size_t i = offset; i < end; ++i) {
70 capturedContent.push_back(decodeCodePoint(_vectorRef.at(i)).toRawValue());
71 }
72 return std::make_shared<VectorMatch>(std::move(captureGroupList), std::move(capturedContent), offset);
73 }
74
75private:
76 [[nodiscard]] static auto decodeCodePoint(const char32_t codePoint) noexcept -> el::text::Char {
77 const auto character = el::text::Char{codePoint};
78 return character.isValidUnicode() ? character : el::text::Char::replacement();
79 }
80
81 const std::vector<char32_t> &_vectorRef;
82 std::size_t _position = 0;
83};
The Match Interfaceο
Match Familiesο
A successful match is represented by one encoding-specific type:
Matchreturnstext::Stringcontent.Match16returnstext::U16Stringcontent.Match32returnstext::U32Stringcontent.
There is no separate view-result family. Core strings are read-only owning values, so matches retain their subject storage and return copy-free slices from it.
Lifetime and Ownershipο
Match objects are shared pointers and are immutable after creation.
The match keeps the complete subject string alive; every value returned by content() also owns the referenced
storage.
It is safe to retain a match or captured string after the source variable, temporary subject or generator has been
destroyed.
Groups and Positionsο
MatchBase provides begin, end, range and group access. Overloads
without a selector address capture group zero, which represents the whole match.
Other groups are selected with
CaptureGroupIndex or a text::String name.
Positions are coordinates in the original encoding:
UTF-8 positions count bytes.
UTF-16 positions count
char16_tcode units, including both units of a surrogate pair.UTF-32 positions count
char32_tcode units.
end() identifies the first unit after the captured range.
content() converts the stored coordinates into a native Core string slice without copying.
Regular Expression Errorsο
Regular-expression parsing, diagnostics and execution failures are reported with
RegExError. The exception derives from
err::RuntimeError and carries a
RegExErrorContext.
try {
const auto expression = re::RegEx::compile(pattern);
} catch (const re::RegExError &error) {
log(error.diagnostic()->toString());
}
Error Contextο
The context separates information that applications commonly need to inspect:
titleis a concise statement of what failed. The inheritedreason()andwhat()contain only this title.descriptionoptionally explains why the operation failed, including limits or relevant values.categoryidentifies the subsystem or failure kind without duplicating it in the title.locationstores optional, zero-based typed line, column and code-point indices.
The corresponding convenience accessors are available directly on RegExError.
Missing location components return the respective noIndex value.
withLineNumber() returns a copy with a replaced zero-based line index and preserves every other context field.
Every RE subsystem follows the same message split.
The title states which operation failed, such as Failed to parse regular expression or
Failed to assemble regular expression.
The description states the concrete cause, including relevant values and limits.
Category and location are never duplicated in either text field.
Diagnosticsο
diagnostic() returns a structured Core diagnostic whose toString() method renders the complete plain-text
diagnostic, including the title, optional description, category and every available location component.
Human-readable locations are rendered one-based, while the inspection API remains zero-based.
RegExError::toString() provides a compact single-line summary in the form <category>: <title>. <description> and
deliberately omits structured location details.
Core Strings and Encodingο
Every RE API that receives a Core string uses tolerant decoding. Malformed UTF-8, UTF-16 or UTF-32 units become U+FFFD and participate normally in pattern parsing, assembler parsing, replacement parsing and matching. These string overloads therefore do not throw encoding errors for malformed units.
Custom input implementations remain exception-transparent.
An encoding error or another runtime error thrown by read(), peek(), skip() or createMatch() propagates
unchanged and is not converted into RegExError.
Categoriesο
Parser and Format identify invalid pattern and replacement syntax.
Assembler identifies invalid diagnostic program text.
Limit and Timeout identify configured resource boundaries.
Engine and Internal identify execution or invariant failures.
Diagnosticsο
The regular expression support in Erbsland Core includes a low-level assembler and disassembler that allow you to inspect, analyze, and even manually construct the internal program executed by the matching engine.
These tools are primarily intended for diagnostics, debugging, testing, and advanced experimentation. They are not required for normal use of the library, but they provide valuable insight into how patterns are translated into executable instructions.
Disassemble Compiled Patternsο
The disassembler can be used to inspect the program generated by the compiler for a given regular expression pattern.
const auto reTag = RegEx::compile(R"((?is)<([a-z]+)([^>]*)>)");
for (const auto &line : diagnostics::Disassembler{reTag}.disassemble()) {
std::cout << line << '\n';
}
This produces a textual representation of the compiled program, including character classes, control flow, and capture group handling:
; Character classes
; ============================================================================
.section &class
$0000: .class ; [a-z]
$0000: .data $000061-$00007A
; Program
; ============================================================================
.section &program
$0000: 0900003c CI CHAR '<'
$0001: 86000000 START CAPTURE 0
$0002: 0c000000 CI CLASS $0000
$0003: 81000002 00000005 SPLIT $0002, $0005
$0005: a6000000 STOP CAPTURE 0
$0006: 86000001 START CAPTURE 1
$0007: 81000009 0000000b SPLIT $0009, $000B
$0009: 2900003e NOT CI CHAR '>'
$000A: c2000007 JUMP $0007
$000B: a6000001 STOP CAPTURE 1
$000C: 0900003e CI CHAR '>'
$000D: 83000000 MATCH
Reading this output is helpful when:
debugging unexpected matching behaviour,
analyzing performance characteristics,
learning how specific pattern constructs are compiled.
Write Custom Programsο
For advanced use cases, you can also write custom matching programs directly using the assembler.
This allows you to bypass the regular expression syntax entirely and construct a program manually using the engineβs instruction set.
using namespace erbsland::text::literals;
const auto program = text::StringList{
"; my custom program"_el,
"loop: CHAR 'a'"_el,
" SPLIT %loop, %end"_el,
"end: MATCH"_el,
};
auto reCustom = diagnostics::Assembler().compile(program);
auto match = reCustom->match("aaaaaa"_el);
std::cout << "Result: " << match->content() << '\n';
Result: aaaaaa
Custom programs are useful for testing the engine, experimenting with new instruction sequences, or creating minimal reproducible examples when investigating bugs.
The assembler accepts text::StringList.
The disassembler returns the same owning Core list type, so listings remain valid independently of the disassembler
object.
Assembler source uses tolerant Core-string decoding.
Malformed UTF-8 units become U+FFFD before tokenization.
Syntax and limit failures are reported as RegExError with an Assembler
category and a zero-based structured source location; the rendered diagnostic presents locations one-based.
Interfaceο
-
class CaptureGroupο
The definition of a match group.
Public Functions
-
constexpr CaptureGroup() noexcept = defaultο
Create an empty capture group.
-
inline constexpr CaptureGroup(const CaptureGroupIndex index, const CaptureRange range, const text::String &name) noexceptο
Create a new match group with the given capture range, and name.
- Parameters:
index β The index of the group. 0 = complete match, 1 = first capture group.
range β The character range for the group.
name β The name of the group.
-
inline constexpr CaptureGroupIndex index() const noexceptο
Get the index of this capture group.
-
inline constexpr bool isEmpty() const noexceptο
Test if the group is empty.
- Returns:
True if begin equals end, false otherwise.
-
inline constexpr std::size_t size() const noexceptο
Get the size of the group.
- Returns:
The number of positions between begin and end.
-
inline constexpr InputPosition begin() const noexceptο
Get the start position for the match.
- Returns:
The begin position (inclusive).
-
inline constexpr InputPosition end() const noexceptο
Get the end position for the match.
- Returns:
The end position (exclusive).
-
inline constexpr CaptureRange range() const noexceptο
Get the range of for the match.
- Returns:
The range.
-
inline void setIndex(const CaptureGroupIndex index) noexceptο
Set the index for the group.
- Parameters:
index β The group index.
-
inline void setBegin(const InputPosition begin) noexceptο
Set the start position for the match.
- Parameters:
begin β The begin position (inclusive).
-
inline void setEnd(const InputPosition end) noexceptο
Set the end position for the match.
- Parameters:
end β The end position (exclusive).
-
constexpr CaptureGroup() noexcept = defaultο
-
using erbsland::re::CaptureGroupList = std::vector<CaptureGroup>ο
A list of capture groups.
-
using erbsland::re::CaptureGroupIndex = uint16_tο
The index of a capture group.
Group index 0 is the full match, 1 is the first capture group, etc.
-
class CaptureRangeο
Represents a range in the input, defined by begin and end positions.
This class is used to represent captured content ranges in regular expression matches. The range is defined as [begin, end], where begin is inclusive and end is exclusive.
Public Functions
-
inline constexpr CaptureRange(const InputPosition begin, const InputPosition end) noexceptο
Create a new capture range with the given begin and end positions.
- Parameters:
begin β The start position of the range (inclusive).
end β The end position of the range (exclusive).
-
inline constexpr bool isEmpty() const noexceptο
Test if the range is empty.
- Returns:
True if begin equals end, false otherwise.
-
inline constexpr std::size_t size() const noexceptο
Get the size of the range.
- Returns:
The number of positions between begin and end.
-
inline constexpr InputPosition begin() const noexceptο
Get the start position of the range.
- Returns:
The begin position (inclusive).
-
inline constexpr InputPosition end() const noexceptο
Get the end position of the range.
- Returns:
The end position (exclusive).
-
inline void setBegin(const InputPosition begin) noexceptο
Set the start position of the range.
- Parameters:
begin β The new begin position (inclusive).
-
inline void setEnd(const InputPosition end) noexceptο
Set the end position of the range.
- Parameters:
end β The new end position (exclusive).
-
inline constexpr CaptureRange(const InputPosition begin, const InputPosition end) noexceptο
-
struct CharAndPositionο
A read character and its start position.
Public Members
-
InputPosition positionο
The start position of the read character.
-
InputPosition positionο
-
class Assemblerο
An assembler for diagnostics, unit test, and experiments.
Please read the documentation for the full syntax of the assembler language.
Public Functions
-
RegExPtr compile(const text::StringList &lines) constο
Compile the given assembler program into a regular expression object.
- Parameters:
lines β The lines of the assembler code to compile.
- Throws:
RegExError β on any compilation error.
- Returns:
The compiled regular expression object.
-
RegExPtr compile(const text::StringList &lines) constο
-
class Disassemblerο
A disassembler for the regular expression engine data.
Public Functions
-
explicit Disassembler(const ConstRegExPtr ®Ex)ο
Create a new instance for the given regular expression.
-
text::StringList disassemble() constο
Disassemble the engine data into human-readable instructions.
-
explicit Disassembler(const ConstRegExPtr ®Ex)ο
-
enum class erbsland::re::ErrorCategory : uint8_tο
The category of an
RegExError.Values:
-
enumerator Parserο
A parser error.
-
enumerator Formatο
A format error in a replacement string.
-
enumerator Assemblerο
An assembler error.
-
enumerator Engineο
An engine error.
-
enumerator Timeoutο
A timeout error.
-
enumerator Limitο
A limit error.
-
enumerator Internalο
An internal error.
-
enumerator Parserο
-
inline text::String erbsland::re::toString(const ErrorCategory category) noexceptο
Convert an error category into a stable, human-readable name.
-
enum class erbsland::re::Feature : uint16_tο
A feature of the regular expression syntax or engine.
Values:
-
enumerator QuotedLiteralsο
Using quotes
\\Q...\\E.
-
enumerator EscapeBellο
The escape sequence
\\afor bell character.
-
enumerator EscapeControlο
The escape sequence
\\cXfor control character.
-
enumerator EscapeEscapeο
The escape sequence
\\efor the escape character.
-
enumerator EscapeFormFeedο
The escape sequence
\\ffor form feed character.
-
enumerator EscapeOctalο
The escape sequence
\\o{nnn}for octal character.
-
enumerator EscapeHexο
The escape sequence
\\xnnand\\x{nnnn}for hexadecimal character.
-
enumerator EscapeLongUnicodeο
The escape sequence
\\Unnnnnnnnfor 32-bit Unicode character.
-
enumerator EscapeHorizontalSpaceο
The escape sequence
\\hfor horizontal space character.
-
enumerator EscapeVerticalSpaceο
The escape sequence
\\vfor vertical space character.
-
enumerator PosixClassesο
Using POSIX character classes like
[:digit:]
-
enumerator AnchorLowercaseZο
Using the anchor
\\zfor the end of the string.
-
enumerator EmptyAlternativesο
Allow empty alternatives, like
(?:a|b|)
-
enumerator EmptyGroupsο
Allow empty groups, like
()
-
enumerator AcceptNullInPatternο
Allow null characters in regular expression patterns.
-
enumerator AcceptNullInInputο
Allow null characters in matching input.
-
enumerator AllCompatibilityο
All compatibility options.
-
enumerator Defaultο
The default value (enable all compatibility features and null characters in input)
-
enumerator QuotedLiteralsο
-
inline text::String erbsland::re::toString(const Feature feature)ο
Convert a feature to a string representation.
-
class Features : public erbsland::util::EnumFlags<Feature, Features>ο
Features for compiling regular expressions.
Public Functions
-
enum class erbsland::re::Flag : uint8_tο
A single flag.
Values:
-
enumerator Noneο
-
enumerator IgnoreCaseο
Ignore case when matching text.
-
enumerator DotAllο
The dot operator also matches newlines.
-
enumerator Asciiο
Restrict
\\w,\\d,\\sto ASCII only matching.
-
enumerator Verboseο
Ignore spacing in the regular expression.
-
enumerator CRLFο
Interpret CRLF line endings like a single LF.
Both characters of such line-endings are preserved when capturing text. This works similar to the folding of multi-code point Unicode characters. E.g. ``a¨`` is interpreted as ``À``, but both code-points are preserved in text.
-
enumerator Noneο
-
inline text::String erbsland::re::toString(const Flag flag)ο
Convert a flag to a string representation.
-
class Flags : public erbsland::util::EnumFlags<Flag, Flags>ο
Flags for constructing a regular expression object.
-
class Input : public erbsland::re::InputBaseο
An abstract input for regular expression matching.
Subclassed by erbsland::re::impl::StreamInput, erbsland::re::impl::StringInput
Public Functions
-
virtual MatchPtr createMatch(CaptureGroupList captureGroupList) = 0ο
Create a match object for this input.
- Parameters:
captureGroupList β The list of capture groups.
- Returns:
An owning match result that holds a copy of the matched text. Implementations may throw encoding errors or other runtime errors; matching operations propagate them unchanged.
-
virtual MatchPtr createMatch(CaptureGroupList captureGroupList) = 0ο
-
class Input16 : public erbsland::re::InputBaseο
An abstract UTF-16 input for regular expression matching.
Subclassed by erbsland::re::impl::U16StringInput
Public Functions
-
virtual Match16Ptr createMatch(CaptureGroupList captureGroupList) = 0ο
Create a match object for this input.
- Parameters:
captureGroupList β The list of capture groups.
- Returns:
An owning match result that holds a copy of the matched text. Implementations may throw encoding errors or other runtime errors; matching operations propagate them unchanged.
-
virtual Match16Ptr createMatch(CaptureGroupList captureGroupList) = 0ο
-
using erbsland::re::Input16Ptr = std::shared_ptr<Input16>ο
A shared pointer to a UTF-16 input instance.
-
class Input32 : public erbsland::re::InputBaseο
An abstract UTF-32 input for regular expression matching.
Subclassed by erbsland::re::impl::U32StringInput
Public Functions
-
virtual Match32Ptr createMatch(CaptureGroupList captureGroupList) = 0ο
Create a match object for this input.
- Parameters:
captureGroupList β The list of capture groups.
- Returns:
An owning match result that holds a copy of the matched text. Implementations may throw encoding errors or other runtime errors; matching operations propagate them unchanged.
-
virtual Match32Ptr createMatch(CaptureGroupList captureGroupList) = 0ο
-
using erbsland::re::Input32Ptr = std::shared_ptr<Input32>ο
A shared pointer to a UTF-32 input instance.
-
class InputBase : public std::enable_shared_from_this<InputBase>ο
The abstract base class for inputs for regular expression matching.
Exceptions raised by input operations propagate unchanged through the matching engine.
Subclassed by erbsland::re::Input, erbsland::re::Input16, erbsland::re::Input32, erbsland::re::impl::NullRejectingInput
Public Functions
-
virtual CharAndPosition read() = 0ο
Read the next character from the input and advance the position.
Implementations must return a valid Unicode scalar value, or
text::Char::endOfData()after exhaustion. Repeated reads after exhaustion must keep returning the end-of-data signal. Implementations may throw encoding errors or other runtime errors; matching operations propagate them unchanged.- Returns:
1. The next character from the input, or the end-of-data signal after exhaustion.
The start position of the read character (the position of the first byte of the read character).
-
virtual CharAndPosition peek() = 0ο
Peek at the next character from the input, do not advance the position.
Implementations must follow the same valid-scalar/end-of-data contract as
read(). Implementations may throw encoding errors or other runtime errors; matching operations propagate them unchanged.- Returns:
1. The next character from the input, or the end-of-data signal after exhaustion.
The start position of the read character (the position of the first byte of the read character).
-
virtual CharAndPosition read() = 0ο
-
using erbsland::re::InputBasePtr = std::shared_ptr<InputBase>ο
A shared pointer to an input instance.
-
using erbsland::re::InputPosition = std::size_tο
A position in the input stream.
This is a valid position in the input. The concrete meaning depends on the used
Inputimplementation.UTF8 => the position of the start byte (char, char8_t) for a character.
UTF16 => the position of the start word (char16_t) for a character.
UTF32 => the position of the character (char32_t).
-
class Match : public erbsland::re::MatchBaseο
An owning match result.
The returned views from
content()are valid for the lifetime of this object.Subclassed by erbsland::re::impl::StreamMatch, erbsland::re::impl::StringMatch
Public Functions
-
text::String content(CaptureGroupIndex groupIndex) constο
Get the content of the specified group.
- Throws:
err::ParameterError β if the group index is invalid.
-
text::String content(const text::String &groupName) constο
Get the content of the specified group.
- Throws:
err::ParameterError β if the group name is invalid.
-
text::String content(CaptureGroupIndex groupIndex) constο
-
using erbsland::re::MatchGenerator = util::CoGenerator<MatchPtr>ο
A generator returning matches.
-
class Match16 : public erbsland::re::MatchBaseο
An owning UTF-16 match result.
The returned views from
content()are valid for the lifetime of this object.Subclassed by erbsland::re::impl::U16StringMatch
Public Functions
-
text::U16String content(CaptureGroupIndex groupIndex) constο
Get the content of the specified group.
- Throws:
err::ParameterError β if the group index is invalid.
-
text::U16String content(const text::String &groupName) constο
Get the content of the specified group.
- Throws:
err::ParameterError β if the group name is invalid.
-
text::U16String content(CaptureGroupIndex groupIndex) constο
-
using erbsland::re::Match16Ptr = std::shared_ptr<Match16>ο
A shared pointer to a UTF-16 match result.
-
using erbsland::re::Match16Generator = util::CoGenerator<Match16Ptr>ο
A generator returning UTF-16 matches.
-
using erbsland::re::Match16List = std::vector<Match16Ptr>ο
A list of UTF-16 matches.
-
class Match32 : public erbsland::re::MatchBaseο
An owning UTF-32 match result.
The returned views from
content()are valid for the lifetime of this object.Subclassed by erbsland::re::impl::U32StringMatch
Public Functions
-
text::U32String content(CaptureGroupIndex groupIndex) constο
Get the content of the specified group.
- Throws:
err::ParameterError β if the group index is invalid.
-
text::U32String content(const text::String &groupName) constο
Get the content of the specified group.
- Throws:
err::ParameterError β if the group name is invalid.
-
text::U32String content(CaptureGroupIndex groupIndex) constο
-
using erbsland::re::Match32Ptr = std::shared_ptr<Match32>ο
A shared pointer to a UTF-32 match result.
-
using erbsland::re::Match32Generator = util::CoGenerator<Match32Ptr>ο
A generator returning UTF-32 matches.
-
using erbsland::re::Match32List = std::vector<Match32Ptr>ο
A list of UTF-32 matches.
-
class MatchBaseο
The abstract baseclass for regular expression matches.
Subclassed by erbsland::re::Match, erbsland::re::Match16, erbsland::re::Match32
Public Functions
-
virtual InputPosition begin() constο
Get the start position of the match.
-
virtual InputPosition begin(CaptureGroupIndex groupIndex) constο
Get the start position of the given group.
- Parameters:
groupIndex β The index of the group.
- Throws:
err::ParameterError β if the group index is invalid.
-
virtual InputPosition begin(const text::String &groupName) constο
Get the start position of the given group.
- Parameters:
groupName β The name of the group.
- Throws:
err::ParameterError β if the group name is invalid.
-
virtual InputPosition end() constο
Get the end position of the match.
The end position points after the last character of the match.
-
virtual InputPosition end(CaptureGroupIndex groupIndex) constο
Get the end position of the given group.
The end position points after the last character of the match.
- Parameters:
groupIndex β The index of the group.
- Throws:
err::ParameterError β if the group index is invalid.
-
virtual InputPosition end(const text::String &groupName) constο
Get the end position of the given group.
The end position points after the last character of the match.
- Parameters:
groupName β The name of the group.
- Throws:
err::ParameterError β if the group name is invalid.
-
virtual CaptureRange range() constο
Get the range of the match.
The range is defined as [begin, end] where begin is inclusive and end is exclusive.
-
virtual CaptureRange range(CaptureGroupIndex groupIndex) constο
Get the range of the given group.
The range is defined as [begin, end] where begin is inclusive and end is exclusive.
- Parameters:
groupIndex β The index of the group.
- Throws:
err::ParameterError β if the group index is invalid.
-
virtual CaptureRange range(const text::String &groupName) constο
Get the range of the given group.
The range is defined as [begin, end] where begin is inclusive and end is exclusive.
- Parameters:
groupName β The group name.
- Throws:
err::ParameterError β if the group name is invalid.
-
virtual const CaptureGroup &group() constο
Get the capture group of the match.
- Returns:
A reference to the capture group instance.
-
virtual const CaptureGroup &group(CaptureGroupIndex groupIndex) constο
Get the capture group of the given group.
- Parameters:
groupIndex β The index of the group.
- Throws:
err::ParameterError β if the group index is invalid.
- Returns:
A reference to the capture group instance.
-
virtual const CaptureGroup &group(const text::String &groupName) constο
Get the capture group of the given group.
- Parameters:
groupName β The name of the group.
- Throws:
err::ParameterError β if the group name is invalid.
- Returns:
A reference to the capture group instance.
-
virtual std::size_t groupCount() const noexceptο
Get the number of capture groups, including the full match.
If there are two capture groups
(a)(b), this function will return 3, as the full match counts as capture group zero((a)(b)).
-
virtual bool hasGroupIndex(CaptureGroupIndex groupIndex) const noexceptο
Test if the given group index exists.
-
virtual InputPosition begin() constο
-
using erbsland::re::MatchBasePtr = std::shared_ptr<MatchBase>ο
A shared pointer to a match base result.
-
class RegExο
A regular expression that is compiled eagerly or on its first use.
The instance is immutable and can safely be shared between threads. A lazy expression compiles its engine exactly once on first use. If compilation fails, the matching operation throws
RegExError; a later operation retries compilation. All Core-string overloads decode malformed units as replacement characters. Exceptions from custom inputs propagate unchanged.Public Types
Public Functions
-
inline const text::AnyString &pattern() const noexceptο
Return the source pattern used to compile this regular expression.
- Returns:
The preserved source pattern.
-
bool isCompiled() const noexceptο
Test if the engine was successfully compiled.
Eager expressions always return
true. This method does not trigger lazy compilation.
-
void compileNow() constο
Compile a lazy expression now, or do nothing if its engine is already available.
- Throws:
RegExError β If the pattern is invalid.
-
MatchPtr match(const text::String &text) constο
Try to match this expression at the start of UTF-8 text.
-
Match16Ptr match(const text::U16String &text) constο
Try to match this expression at the start of UTF-16 text.
-
Match32Ptr match(const text::U32String &text) constο
Try to match this expression at the start of UTF-32 text.
-
MatchPtr match(const InputPtr &input) constο
Try to match this expression at the start of a custom UTF-8 input.
-
MatchPtr match(const stream::TextInputStreamPtr &input) constο
Try to match this expression at the current position of a seekable text stream.
- Throws:
err::ParameterError β if the stream is null or does not support positioning.
stream::StreamError β if the stream times out or fails.
-
Match16Ptr match(const Input16Ptr &input) constο
Try to match this expression at the start of a custom UTF-16 input.
-
Match32Ptr match(const Input32Ptr &input) constο
Try to match this expression at the start of a custom UTF-32 input.
-
MatchPtr fullMatch(const text::String &text) constο
Try to match this expression against all UTF-8 text.
-
Match16Ptr fullMatch(const text::U16String &text) constο
Try to match this expression against all UTF-16 text.
-
Match32Ptr fullMatch(const text::U32String &text) constο
Try to match this expression against all UTF-32 text.
-
MatchPtr fullMatch(const InputPtr &input) constο
Try to match this expression against the complete custom UTF-8 input.
-
MatchPtr fullMatch(const stream::TextInputStreamPtr &input) constο
Try to match this expression against all remaining text in a seekable text stream.
- Throws:
err::ParameterError β if the stream is null or does not support positioning.
stream::StreamError β if the stream times out or fails.
-
Match16Ptr fullMatch(const Input16Ptr &input) constο
Try to match this expression against the complete custom UTF-16 input.
-
Match32Ptr fullMatch(const Input32Ptr &input) constο
Try to match this expression against the complete custom UTF-32 input.
-
Match16Ptr findFirst(const text::U16String &text) constο
Find the first match in UTF-16 text.
-
Match32Ptr findFirst(const text::U32String &text) constο
Find the first match in UTF-32 text.
-
MatchPtr findFirst(const stream::TextInputStreamPtr &input) constο
Find the first match in a seekable text stream.
- Throws:
err::ParameterError β if the stream is null or does not support positioning.
stream::StreamError β if the stream times out or fails.
-
Match16Ptr findFirst(const Input16Ptr &input) constο
Find the first match in a custom UTF-16 input.
-
Match32Ptr findFirst(const Input32Ptr &input) constο
Find the first match in a custom UTF-32 input.
-
MatchGenerator findAll(const text::String &text) constο
Lazily find all matches in UTF-8 text.
-
Match16Generator findAll(const text::U16String &text) constο
Lazily find all matches in UTF-16 text.
-
Match32Generator findAll(const text::U32String &text) constο
Lazily find all matches in UTF-32 text.
-
MatchGenerator findAll(InputPtr input) constο
Lazily find all matches in a custom UTF-8 input.
-
MatchGenerator findAll(stream::TextInputStreamPtr input) constο
Lazily find all matches in a seekable text stream.
- Throws:
err::ParameterError β if the stream is null or does not support positioning.
stream::StreamError β if the stream times out or fails.
-
Match16Generator findAll(Input16Ptr input) constο
Lazily find all matches in a custom UTF-16 input.
-
Match32Generator findAll(Input32Ptr input) constο
Lazily find all matches in a custom UTF-32 input.
-
Match16List collectAll(const text::U16String &text) constο
Collect all matches in UTF-16 text.
-
Match32List collectAll(const text::U32String &text) constο
Collect all matches in UTF-32 text.
-
MatchList collectAll(const stream::TextInputStreamPtr &input) constο
Collect all matches in a seekable text stream.
- Throws:
err::ParameterError β if the stream is null or does not support positioning.
stream::StreamError β if the stream times out or fails.
-
Match16List collectAll(const Input16Ptr &input) constο
Collect all matches in a custom UTF-16 input.
-
Match32List collectAll(const Input32Ptr &input) constο
Collect all matches in a custom UTF-32 input.
Public Static Functions
-
static RegExPtr compile(text::AnyString pattern, Flags flags = {}, const Settings &settings = {})ο
Compile a regular expression from a UTF-8 pattern.
- Parameters:
pattern β The regular expression pattern.
flags β The initial flags for the regular expression.
settings β The settings for the parser and resulting engine.
- Throws:
RegExError β If the pattern is invalid.
- Returns:
A shared pointer to the compiled regular expression.
-
static RegExPtr lazyCompile(text::AnyString pattern, Flags flags = {}, const Settings &settings = {})ο
Create a regular expression whose engine is compiled on first use.
The pattern is retained without validation. Call
compileNow()to explicitly trigger compilation.- Parameters:
pattern β The regular expression pattern.
flags β The initial flags for the regular expression.
settings β The settings for the parser and resulting engine.
- Returns:
A shared pointer to the lazy regular expression.
-
struct PrivateTagο
-
inline const text::AnyString &pattern() const noexceptο
-
using erbsland::re::ConstRegExPtr = std::shared_ptr<const RegEx>ο
A shared pointer to an immutable regular expression.
-
class RegExError : public erbsland::err::RuntimeErrorο
An error raised by regular-expression parsing, compilation, diagnostics, or matching.
See: Regular Expressions
Public Functions
-
RegExError(ErrorCategory category, text::String title) noexceptο
Create an error with a concise title.
-
RegExError(ErrorCategory category, text::String title, unit::CodeLocation location) noexceptο
Create an error with a title and source location.
-
RegExError(ErrorCategory category, text::String title, text::String description, unit::CodeLocation location = {}) noexceptο
Create an error with a title, description, and optional source location.
-
explicit RegExError(RegExErrorContext context) noexceptο
Create an error from complete context.
-
virtual text::String toString() const noexcept overrideο
Create a compact one-line summary containing category, title and description.
-
virtual err::DiagnosticConstPtr diagnostic() const overrideο
Create the complete structured diagnostic.
-
inline const RegExErrorContext &context() const noexceptο
Get the complete error context.
-
inline ErrorCategory category() const noexceptο
Get the error category.
-
inline unit::CodeLocation location() const noexceptο
Get the source location.
-
inline unit::ColumnIndex column() const noexceptο
Get the source column index.
-
RegExError withLineNumber(unit::LineIndex lineNumber) const noexceptο
Create a copy of this error with the given zero-based line index.
-
RegExError(ErrorCategory category, text::String title) noexceptο
-
class RegExErrorContextο
Context for a regular-expression error.
Public Functions
-
inline explicit RegExErrorContext(ErrorCategory category, text::String title, text::String description = {}, unit::CodeLocation location = {}) noexceptο
Create context for a regular-expression error.
- Parameters:
category β The error category.
title β A concise description of what went wrong.
description β An optional explanation of why the error occurred.
location β The optional source location.
-
inline ErrorCategory category() const noexceptο
Get the error category.
-
inline RegExErrorContext &setCategory(const ErrorCategory category) noexceptο
Set the error category.
-
inline RegExErrorContext &setTitle(text::String title) noexceptο
Set the concise error title.
-
inline RegExErrorContext &setDescription(text::String description) noexceptο
Set the detailed error description.
-
inline unit::CodeLocation location() const noexceptο
Get the source location.
-
inline RegExErrorContext &setLocation(const unit::CodeLocation location) noexceptο
Set the source location.
-
inline unit::ColumnIndex column() const noexceptο
Get the source column index.
-
inline explicit RegExErrorContext(ErrorCategory category, text::String title, text::String description = {}, unit::CodeLocation location = {}) noexceptο
-
class Settingsο
Settings for compiling regular expression patterns.
Public Functions
-
inline unit::CpLength maximumPatternLength() const noexceptο
The maximum pattern length in characters.
-
inline void setMaximumPatternLength(unit::CpLength length) noexceptο
Set the maximum pattern length.
- Parameters:
length β A length in characters, or zero to reset back to default.
-
inline std::size_t maximumGroupNestingDepth() const noexceptο
The maximum group nesting depth.
-
inline void setMaximumGroupNestingDepth(std::size_t depth) noexceptο
Set the maximum group nesting depth.
- Parameters:
depth β A depth in levels, or zero to reset back to default.
-
inline std::size_t maximumCaptureGroupCount() const noexceptο
The maximum capture group count.
-
inline void setMaximumCaptureGroupCount(std::size_t count) noexceptο
Set the maximum capture group count.
- Parameters:
count β The maximum capture group count or zero to reset back to default.
-
inline std::size_t maximumSequenceLength() const noexceptο
The maximum sequence length.
-
inline void setMaximumSequenceLength(std::size_t length) noexceptο
Set the maximum sequence length.
- Parameters:
length β A length in characters, or zero to reset back to default.
-
inline std::size_t maximumAlternativeCount() const noexceptο
The maximum alternative count.
-
inline void setMaximumAlternativeCount(std::size_t count) noexceptο
Set the maximum alternative count.
- Parameters:
count β A count of alternatives, or zero to reset back to default.
-
inline std::size_t maximumQuantifierCount() const noexceptο
Get the maximum quantifier count.
This is the maximum for quantifier expressions like
{n,m}
-
inline void setMaximumQuantifierCount(std::size_t count) noexceptο
Set the maximum quantifier count.
- Parameters:
count β The maximum quantifier count, or zero to reset back to default.
-
inline std::chrono::milliseconds timeout() const noexceptο
Access the current timeout.
- Returns:
The current timeout. Zero means no timeout.
-
inline void setTimeout(const std::chrono::milliseconds timeout) noexceptο
Set a timeout for all calls.
- Parameters:
timeout β The timeout to set, or zero to disable timeout.
-
inline bool hasFeature(const Feature feature) const noexceptο
Test if a feature is enabled.
- Parameters:
feature β The feature to test.
-
inline void disableFeature(const Feature feature) noexceptο
Disable a feature.
- Parameters:
feature β The feature to disable.
-
inline unit::CpLength maximumPatternLength() const noexceptο