Module
LinkRegex.compile validates a Unicode pattern before searching, splitting, or replacing text. Match values contain UTF-8 byte boundaries and independent capture snapshots.
Why
LinkA compiled pattern keeps one search language and one match sequence across Boolean searches, match extraction, splitting, and replacement.
Availability
LinkImport std.regex in language mode 5.21. The current compiler selects std/regex.tpz for this language mode. Availability in other released editions and inclusion in each installed distribution are Pending.
Exported types
Linkexport type Regex = Regex
export type Match = Match
Type members keep the compiler-owned type name shown in their declarations. Importing a module does not create a new type identity.
Public API
LinkPending contracts
LinkCompile the Unicode regular expression language
LinkCompile the Unicode regular expression language
Regex.compile evaluates its pattern string once and returns Ok containing an immutable compiled pattern. Malformed or unsupported syntax returns Err containing a nonempty explanatory string. Compile errors are data and do not issue a diagnostic. Error wording has no fixed spelling.
Patterns match Unicode scalar values without Unicode normalization. Ordinary characters match themselves. Dot matches any scalar except a line feed. Concatenation, ordered alternation with a vertical bar, capturing groups, and noncapturing groups are supported. The empty pattern and empty alternatives are valid.
Character classes support literal members, inclusive scalar ranges, and a leading caret for negation. An inverted range is invalid. Escape a metacharacter with a backslash to match it literally. The escapes for n, r, and t match line feed, carriage return, and tab.
The quantifiers *, +, and ? mean zero or more, one or more, and zero or one. Counted forms {m}, {m,}, and {m,n} use nonnegative decimal counts with m no greater than n. A following question mark makes a repetition lazy. Unescaped braces outside classes delimit a repetition. Quantifiers require an atom and cannot directly repeat an anchor. Possessive quantifiers are invalid.
A caret and dollar anchor the beginning and end of the input. The escapes \A and \z keep those whole-input meanings. Inline flags i, m, and s select Unicode simple case folding, line anchors, and dot matching line feeds. The forms (?flags) and (?flags:pattern) set flags for the remaining group or a nested group. A minus sign clears subsequent flags.
Case folding uses the C and S mappings in Unicode 16.0 CaseFolding.txt and excludes the locale-specific T mappings and multiscalar F mappings. The m flag also permits a caret after a line feed and a dollar before a line feed. It does not remove a carriage return before that line feed.
Unicode properties use Unicode 16.0. The class \d is Decimal_Number. The class \s is White_Space. The class \w combines Alphabetic, Mark, Decimal_Number, Connector_Punctuation, and Join_Control. Uppercase D, S, and W negate those classes. The escapes \b and \B test a boundary or nonboundary between word and nonword scalars. Missing text at either end is nonword.
The forms \p{name} and \P{name} match or negate a Unicode general category, script, or binary property. Use a category alias, a binary-property alias, or Script= followed by a script alias. Names use Unicode 16.0 aliases and ignore case, spaces, and underscores. An unknown property or value is invalid. Unicode matching cannot be disabled to match a partial UTF-8 sequence.
Named captures use (?<name>pattern). Names are case sensitive unique ASCII identifiers beginning with a letter or underscore and continuing with letters, digits, or underscores. The alternative spelling (?P<name>pattern) is invalid.
Backreferences, lookaround, conditionals, atomic groups, and unknown alphanumeric escapes are invalid. Compile performs no I/O and never changes the pattern string.
Why
A documented Unicode pattern language handles text independently of its UTF-8 encoding. Unicode 16.0 aligns property tests with the text library edition. Simple case folding compares scalars without inserting extra characters or depending on a locale. Excluding backreferences and lookaround preserves a regular language. One named capture spelling avoids an alias while compile errors let applications validate patterns as input.
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 92 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 272 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 307 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 359 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 460 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 514 - Public/16.0.0/ucd/PropertyAliases.txt at
16.0.0· Unicode 16.0 property aliases - Public/16.0.0/ucd/CaseFolding.txt at
16.0.0· Default simple case folding using C and S mappings -
topaz.stdlib.contract.regex-compileatworking-tree - topaz.decision.regex-pattern-language.1 at
topaz.decisi
Compile literals, classes, grouping, and anchors
Linkimport std.regex { Regex }import std.iomatch (Regex.compile("^(?:ab)+[0-9]?$")) {case Ok(pattern) => {let present = pattern.isMatch("abab2")let absent = pattern.isMatch("zabab2")io.writeLine("{present}")io.writeLine("{absent}")}case Err(_) => io.writeLine("compile failed")}
true false
Expected result
Expected result
Execution completes. Exit code 0.
truefalse
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 92 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 272 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 307 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 359 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 460 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 514 - Public/16.0.0/ucd/PropertyAliases.txt at
16.0.0· Unicode 16.0 property aliases - Public/16.0.0/ucd/CaseFolding.txt at
16.0.0· Default simple case folding using C and S mappings -
topaz.stdlib.contract.regex-compileatworking-tree - topaz.decision.regex-pattern-language.1 at
topaz.decisi
Return errors for malformed and unsupported pattern syntax
Linkimport std.regex { Regex }import std.iofor text in (["[", "(", "a**", "[z-a]", "(?=a)", "(?<a>x)(?<a>y)", "\\q"]) {match (Regex.compile(text)) {case Err(message) => io.writeLine("{message != ""}")case Ok(_) => io.writeLine("accepted")}}
true true true true true true true
Expected result
Expected result
Execution completes. Exit code 0.
truetruetruetruetruetruetrue
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 92 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 272 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 307 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 359 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 460 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 514 - Public/16.0.0/ucd/PropertyAliases.txt at
16.0.0· Unicode 16.0 property aliases - Public/16.0.0/ucd/CaseFolding.txt at
16.0.0· Default simple case folding using C and S mappings -
topaz.stdlib.contract.regex-compileatworking-tree - topaz.decision.regex-pattern-language.1 at
topaz.decisi
Match bounded repetition
Linkimport std.regex { Regex }import std.iomatch (Regex.compile("a\{2,3\}")) {case Ok(pattern) => {match (pattern.find("aaaa")) {case Some(found) => io.writeLine(found.text)case None() => io.writeLine("no match")}}case Err(_) => io.writeLine("compile failed")}
aaa
Expected result
Expected result
Execution completes. Exit code 0.
aaa
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 92 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 272 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 307 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 359 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 460 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 514 - Public/16.0.0/ucd/PropertyAliases.txt at
16.0.0· Unicode 16.0 property aliases - Public/16.0.0/ucd/CaseFolding.txt at
16.0.0· Default simple case folding using C and S mappings -
topaz.stdlib.contract.regex-compileatworking-tree - topaz.decision.regex-pattern-language.1 at
topaz.decisi
Choose the shortest successful lazy repetition
Linkimport std.regex { Regex }import std.iomatch (Regex.compile("a+?")) {case Ok(pattern) => {match (pattern.find("aaa")) {case Some(found) => io.writeLine(found.text)case None() => io.writeLine("no match")}}case Err(_) => io.writeLine("compile failed")}
a
Expected result
Expected result
Execution completes. Exit code 0.
a
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 92 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 272 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 307 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 359 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 460 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 514 - Public/16.0.0/ucd/PropertyAliases.txt at
16.0.0· Unicode 16.0 property aliases - Public/16.0.0/ucd/CaseFolding.txt at
16.0.0· Default simple case folding using C and S mappings -
topaz.stdlib.contract.regex-compileatworking-tree - topaz.decision.regex-pattern-language.1 at
topaz.decisi
Apply scoped case, line, and dot flags
Linkimport std.regex { Regex }import std.iofunction show(patternText: string, text: string) -> () {match (Regex.compile(patternText)) {case Ok(pattern) => io.writeLine("{pattern.isMatch(text)}")case Err(_) => io.writeLine("compile failed")}}show("(?i:ab)", "AB")show("(?m:^b$)", "a\nb\nc")show("(?s:a.b)", "a\nb")show("(?i:σ)", "ς")show("(?i:ss)", "ß")
true true true true false
Expected result
Expected result
Execution completes. Exit code 0.
truetruetruetruefalse
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 92 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 272 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 307 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 359 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 460 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 514 - Public/16.0.0/ucd/PropertyAliases.txt at
16.0.0· Unicode 16.0 property aliases - Public/16.0.0/ucd/CaseFolding.txt at
16.0.0· Default simple case folding using C and S mappings -
topaz.stdlib.contract.regex-compileatworking-tree - topaz.decision.regex-pattern-language.1 at
topaz.decisi
Use Unicode digit, word, and whitespace classes
Linkimport std.regex { Regex }import std.iofunction show(patternText: string, text: string) -> () {match (Regex.compile(patternText)) {case Ok(pattern) => io.writeLine("{pattern.isMatch(text)}")case Err(_) => io.writeLine("compile failed")}}show("^\\d+$", "١٢")show("^\\w+$", "한")show("^\\s$", " ")
true true true
Expected result
Expected result
Execution completes. Exit code 0.
truetruetrue
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 92 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 272 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 307 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 359 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 460 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 514 - Public/16.0.0/ucd/PropertyAliases.txt at
16.0.0· Unicode 16.0 property aliases - Public/16.0.0/ucd/CaseFolding.txt at
16.0.0· Default simple case folding using C and S mappings -
topaz.stdlib.contract.regex-compileatworking-tree - topaz.decision.regex-pattern-language.1 at
topaz.decisi
Match a Unicode general category
Linkimport std.regex { Regex }import std.iomatch (Regex.compile("^\\p\{Letter\}+$")) {case Ok(pattern) => {let present = pattern.isMatch("한α")io.writeLine("{present}")}case Err(_) => io.writeLine("compile failed")}
true
Expected result
Expected result
Execution completes. Exit code 0.
true
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 92 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 272 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 307 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 359 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 460 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 514 - Public/16.0.0/ucd/PropertyAliases.txt at
16.0.0· Unicode 16.0 property aliases - Public/16.0.0/ucd/CaseFolding.txt at
16.0.0· Default simple case folding using C and S mappings -
topaz.stdlib.contract.regex-compileatworking-tree - topaz.decision.regex-pattern-language.1 at
topaz.decisi
Use complemented classes and zero-width assertions
Linkimport std.regex { Regex }import std.iofunction show(patternText: string, text: string) -> () {match (Regex.compile(patternText)) {case Ok(pattern) => io.writeLine("{pattern.isMatch(text)}")case Err(_) => io.writeLine("compile failed")}}show("^\\D+$", "abc")show("\\Aab\\z", "ab")show("\\bcat\\b", "a cat!")
true true true
Expected result
Expected result
Execution completes. Exit code 0.
truetruetrue
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 92 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 272 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 307 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 359 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 460 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 514 - Public/16.0.0/ucd/PropertyAliases.txt at
16.0.0· Unicode 16.0 property aliases - Public/16.0.0/ucd/CaseFolding.txt at
16.0.0· Default simple case folding using C and S mappings -
topaz.stdlib.contract.regex-compileatworking-tree - topaz.decision.regex-pattern-language.1 at
topaz.decisi
Use one named capture spelling
Linkimport std.regex { Regex }import std.iofor text in (["(?<word>a)", "(?P<word>a)"]) {match (Regex.compile(text)) {case Ok(_) => io.writeLine("accepted")case Err(_) => io.writeLine("invalid pattern")}}
accepted invalid pattern
Expected result
Expected result
Execution completes. Exit code 0.
acceptedinvalid pattern
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 92 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 272 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 307 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 359 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 460 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 514 - Public/16.0.0/ucd/PropertyAliases.txt at
16.0.0· Unicode 16.0 property aliases - Public/16.0.0/ucd/CaseFolding.txt at
16.0.0· Default simple case folding using C and S mappings -
topaz.stdlib.contract.regex-compileatworking-tree - topaz.decision.regex-pattern-language.1 at
topaz.decisi
Reject a backreference instead of interpreting it as a literal
Linkimport std.regex { Regex }import std.iomatch (Regex.compile("(a)\\1")) {case Err(_) => io.writeLine("invalid pattern")case Ok(_) => io.writeLine("accepted")}
invalid pattern
Expected result
Expected result
Execution completes. Exit code 0.
invalid pattern
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 92 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 272 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 307 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 359 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 460 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 514 - Public/16.0.0/ucd/PropertyAliases.txt at
16.0.0· Unicode 16.0 property aliases - Public/16.0.0/ucd/CaseFolding.txt at
16.0.0· Default simple case folding using C and S mappings -
topaz.stdlib.contract.regex-compileatworking-tree - topaz.decision.regex-pattern-language.1 at
topaz.decisi
Search from the left and advance through nonoverlapping matches
LinkSearch from the left and advance through nonoverlapping matches
Regex.isMatch reports whether a match exists anywhere in the input. Regex.find returns Some containing the first match or None() when no match exists. Regex.findAll returns every nonoverlapping match in search order and returns an empty array when no match exists.
Search begins at the earliest Unicode scalar boundary that permits the complete pattern to match. At that position alternatives are tried in pattern order. Greedy repetitions prefer more scalars and lazy repetitions prefer fewer scalars while still allowing the rest of the pattern to match.
After a nonempty match, findAll resumes at its exclusive end. After an empty match, it resumes at the next Unicode scalar boundary. An empty match directly at the end of the preceding nonempty match is skipped and search advances to the next scalar boundary.
An empty pattern visits every scalar boundary, including both ends. The empty input has one boundary and produces one empty match for an empty pattern. Matching never splits the UTF-8 bytes of a scalar.
Regex.split and Regex.replaceAll use the same ordered match sequence as findAll. Repeated calls start a new search and do not retain a cursor. The input string and compiled pattern are unchanged.
The receiver is evaluated once before the positional arguments, which are evaluated once from left to right. Search does not invoke user callbacks or access external state. No match is an ordinary result and does not produce a diagnostic.
Why
One ordered match sequence makes searching, splitting, and replacement agree. Advancing after an empty match ensures progress without splitting a Unicode scalar. Boolean search is distinct from extracting Match data and does not introduce regex membership through the in operator.
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 115 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 144 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 193 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 524 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 548 -
topaz.stdlib.contract.regex-searchatworking-tree - topaz.decision.regex-match-sequence.1 at
topaz.decisi
Choose the first successful alternative at the leftmost position
Linkimport std.regex { Regex }import std.iomatch (Regex.compile("a|ab")) {case Ok(pattern) => {match (pattern.find("zab")) {case Some(found) => io.writeLine("{found.start}:{found.end}:{found.text}")case None() => io.writeLine("no match")}let present = pattern.isMatch("zab")let absent = pattern.isMatch("zzz")io.writeLine("{present}:{absent}")match (pattern.find("zzz")) {case None() => io.writeLine("none")case Some(_) => io.writeLine("present")}let matches = pattern.findAll("zzz")io.writeLine("{matches.length}")}case Err(_) => io.writeLine("compile failed")}
1:2:a true:false none 0
Expected result
Expected result
Execution completes. Exit code 0.
1:2:atrue:falsenone0
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 115 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 144 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 193 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 524 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 548 -
topaz.stdlib.contract.regex-searchatworking-tree - topaz.decision.regex-match-sequence.1 at
topaz.decisi
Choose a group alternative that allows the complete pattern to match
Linkimport std.regex { Regex }import std.iomatch (Regex.compile("(a|ab)c")) {case Ok(pattern) => {match (pattern.find("abc")) {case Some(found) => io.writeLine(found.text)case None() => io.writeLine("no match")}}case Err(_) => io.writeLine("compile failed")}
abc
Expected result
Expected result
Execution completes. Exit code 0.
abc
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 115 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 144 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 193 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 524 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 548 -
topaz.stdlib.contract.regex-searchatworking-tree - topaz.decision.regex-match-sequence.1 at
topaz.decisi
Return nonoverlapping matches in input order
Linkimport std.regex { Regex }import std.iomatch (Regex.compile("aa")) {case Ok(pattern) => {for found in (pattern.findAll("aaaaa")) {io.writeLine("{found.start}:{found.end}:{found.text}")}}case Err(_) => io.writeLine("compile failed")}
0:2:aa 2:4:aa
Expected result
Expected result
Execution completes. Exit code 0.
0:2:aa2:4:aa
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 115 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 144 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 193 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 524 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 548 -
topaz.stdlib.contract.regex-searchatworking-tree - topaz.decision.regex-match-sequence.1 at
topaz.decisi
Visit each boundary for an empty pattern and the empty input
Linkimport std.regex { Regex }import std.iomatch (Regex.compile("")) {case Ok(pattern) => {for found in (pattern.findAll("ab")) {io.writeLine("{found.start}:{found.end}")}io.writeLine("empty input")for found in (pattern.findAll("")) {io.writeLine("{found.start}:{found.end}")}}case Err(_) => io.writeLine("compile failed")}
0:0 1:1 2:2 empty input 0:0
Expected result
Expected result
Execution completes. Exit code 0.
0:01:12:2empty input0:0
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 115 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 144 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 193 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 524 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 548 -
topaz.stdlib.contract.regex-searchatworking-tree - topaz.decision.regex-match-sequence.1 at
topaz.decisi
Skip an empty match directly after a nonempty match
Linkimport std.regex { Regex }import std.iomatch (Regex.compile("a*")) {case Ok(pattern) => {for found in (pattern.findAll("ab")) {io.writeLine("{found.start}:{found.end}:{found.text}")}}case Err(_) => io.writeLine("compile failed")}
0:1:a 2:2:
Expected result
Expected result
Execution completes. Exit code 0.
0:1:a2:2:
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 115 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 144 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 193 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 524 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 548 -
topaz.stdlib.contract.regex-searchatworking-tree - topaz.decision.regex-match-sequence.1 at
topaz.decisi
Return no match after scanning a longer valid input
Linkimport std.regex { Regex }import std.iolet mut text = "a"for step in (0 .. 17) {text = text + text}match (Regex.compile("z")) {case Ok(pattern) => io.writeLine("{pattern.isMatch(text)}")case Err(_) => io.writeLine("compile failed")}
false
Expected result
Expected result
Execution completes. Exit code 0.
false
Source evidence
- compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 115 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 144 - compiler/crates/topaz_value/src/value/regex.rs at
912a5e86e1f9· 193 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 524 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 548 -
topaz.stdlib.contract.regex-searchatworking-tree - topaz.decision.regex-match-sequence.1 at
topaz.decisi
Read match boundaries and capture snapshots
LinkRead match boundaries and capture snapshots
Match.start and Match.end are read-only nonnegative UTF-8 byte offsets in the original input. They follow the inclusive start and exclusive end of byte intervals. Both are scalar boundaries and the end does not exceed the UTF-8 byte length of the input.
Match.text is the matched substring. An empty match has equal start and end and an empty text value. The offsets are not string grapheme indexes. A match may select a combining mark inside a grapheme.
Encoding the original input with encodeUtf8, slicing its bytes from start to end, and calling decodeUtf8 returns Ok containing Match.text. This relationship also holds for non-ASCII input.
Match.groups returns an independent array indexed by capture number. Entry zero is Some containing the entire match. Capturing parentheses are numbered from one in opening-parenthesis order. Named groups participate in the same numbering and noncapturing groups do not.
A nonparticipating capture has value None(). A participating empty capture has value Some containing an empty string. A repeated capture retains the last participating capture in the selected match.
Match.named returns an independent map from capture names to captured strings. A nonparticipating named capture is absent. A participating empty named capture is present with an empty string. Names are inserted in ascending ASCII order.
Reading a Match field evaluates its receiver once and does not modify the Match or input. Mutating a groups array or named map does not affect a later field read. Field access cannot fail for a Match value.
Why
Byte offsets identify every exact match even when a pattern selects part of a grapheme. The byte-slice relationship makes those offsets usable without confusing them with text indexing. Optional numbered captures and omitted named entries distinguish absence from a captured empty string.
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 453 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 465 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 478 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 488 - compiler/crates/topaz_value/src/value/members.rs at
912a5e86e1f9· 518 -
topaz.stdlib.contract.regex-matchatworking-tree - topaz.decision.regex-byte-offsets.1 at
topaz.decisi
Report UTF-8 byte offsets for non-ASCII matches
Linkimport std.regex { Regex }import std.iofunction show(patternText: string, text: string) -> () {match (Regex.compile(patternText)) {case Ok(pattern) => {match (pattern.find(text)) {case Some(found) => io.writeLine("{found.start}:{found.end}:{found.text}")case None() => io.writeLine("no match")}}case Err(_) => io.writeLine("compile failed")}}show("한", "é한🙂")show("́", "éx")
2:5:한 1:3:́
Expected result
Expected result
Execution completes. Exit code 0.
2:5:한1:3:́
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 453 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 465 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 478 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 488 - compiler/crates/topaz_value/src/value/members.rs at
912a5e86e1f9· 518 -
topaz.stdlib.contract.regex-matchatworking-tree - topaz.decision.regex-byte-offsets.1 at
topaz.decisi
Recover a match through the byte slice identified by its offsets
Linkimport std.regex { Regex }import std.iolet text = "한x"match (Regex.compile("한")) {case Ok(pattern) => {match (pattern.find(text)) {case Some(found) => {let bytes = text.encodeUtf8().slice(found.start, found.end)match (bytes.decodeUtf8()) {case Ok(decoded) => io.writeLine(decoded)case Err(_) => io.writeLine("invalid UTF-8 slice")}}case None() => io.writeLine("no match")}}case Err(_) => io.writeLine("compile failed")}
한
Expected result
Expected result
Execution completes. Exit code 0.
한
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 453 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 465 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 478 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 488 - compiler/crates/topaz_value/src/value/members.rs at
912a5e86e1f9· 518 -
topaz.stdlib.contract.regex-matchatworking-tree - topaz.decision.regex-byte-offsets.1 at
topaz.decisi
Keep capture zero and distinguish missing and empty captures
Linkimport std.regex { Regex }import std.iomatch (Regex.compile("(?<word>a)(b)?()")) {case Ok(pattern) => {match (pattern.find("a")) {case Some(found) => {io.writeLine("{found.groups.length}")for group in (found.groups) {match (group) {case Some(text) => io.writeLine("some={text}")case None() => io.writeLine("none")}}}case None() => io.writeLine("no match")}}case Err(_) => io.writeLine("compile failed")}
4 some=a some=a none some=
Expected result
Expected result
Execution completes. Exit code 0.
4some=asome=anonesome=
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 453 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 465 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 478 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 488 - compiler/crates/topaz_value/src/value/members.rs at
912a5e86e1f9· 518 -
topaz.stdlib.contract.regex-matchatworking-tree - topaz.decision.regex-byte-offsets.1 at
topaz.decisi
Omit absent named captures and retain a captured empty string
Linkimport std.regex { Regex }import std.iomatch (Regex.compile("(?<z>a)?(?<a>b*)")) {case Ok(pattern) => {match (pattern.find("")) {case Some(found) => {let mut snapshot = found.namedlet hasOptional = snapshot.containsKey("z")io.writeLine("{hasOptional}")match (snapshot.get("a")) {case Some(text) => io.writeLine("some={text}")case None() => io.writeLine("none")}snapshot.insert("a", "changed")match (found.named.get("a")) {case Some(text) => io.writeLine("again={text}")case None() => io.writeLine("none")}}case None() => io.writeLine("no match")}}case Err(_) => io.writeLine("compile failed")}
false some= again=
Expected result
Expected result
Execution completes. Exit code 0.
falsesome=again=
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 453 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 465 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 478 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 488 - compiler/crates/topaz_value/src/value/members.rs at
912a5e86e1f9· 518 -
topaz.stdlib.contract.regex-matchatworking-tree - topaz.decision.regex-byte-offsets.1 at
topaz.decisi
Split and replace using the shared match sequence
LinkSplit and replace using the shared match sequence
Regex.split returns the input portions between the matches selected by findAll. Delimiters disappear and capture groups are not inserted. Empty portions at either end and between adjacent delimiters are retained. No match produces an array containing the original input.
Regex.replaceAll replaces the same nonoverlapping matches while copying all text between them unchanged. No match returns the original text. The operation does not search inserted replacement text.
Replacement references use a dollar sign followed by a braced capture number or name. Capture zero denotes the complete match. An unknown or nonparticipating capture expands to an empty string. Two dollar signs produce one literal dollar.
A replacement selector is a nonnegative decimal capture number or an ASCII capture name. Dollar text that is neither a double dollar nor a well-formed braced selector is literal. Unbraced dollar names and numbers do not form references. Expansion is performed once and captured dollar text is not expanded again.
An empty pattern splits at every scalar boundary and inserts replacement text at those same boundaries. The adjacent-empty-match rule from findAll also applies when a nonempty match is followed by an empty candidate.
The receiver is evaluated once before text and replacement arguments, which are evaluated once from left to right. Splitting and replacement leave the original string and Regex unchanged. They have no external effects and do not call a user callback.
Why
Using one match sequence prevents a search from disagreeing with a later replacement. Braced capture references have one spelling and an explicit end, so a capture name cannot absorb following replacement text.
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 576 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 607 - compiler/crates/topaz_product_runtime/src/runtime/call.rs at
912a5e86e1f9· 1019 -
topaz.stdlib.contract.regex-transformatworking-tree - topaz.decision.regex-capture-replacement.1 at
topaz.decisi
Retain empty split fields without inserting captures
Linkimport std.regex { Regex }import std.iomatch (Regex.compile("(,)")) {case Ok(pattern) => {for field in (pattern.split(",a,,b,")) {io.writeLine("[{field}]")}for field in (pattern.split("plain")) {io.writeLine("[{field}]")}}case Err(_) => io.writeLine("compile failed")}
[] [a] [] [b] [] [plain]
Expected result
Expected result
Execution completes. Exit code 0.
[][a][][b][][plain]
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 576 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 607 - compiler/crates/topaz_product_runtime/src/runtime/call.rs at
912a5e86e1f9· 1019 -
topaz.stdlib.contract.regex-transformatworking-tree - topaz.decision.regex-capture-replacement.1 at
topaz.decisi
Expand braced capture references and a literal dollar
Linkimport std.regex { Regex }import std.iomatch (Regex.compile("(?<word>[a-z]+)([0-9]+)?")) {case Ok(pattern) => {let replacement = "$\{word\}/$\{0\}/$\{2\}/$\{missing\}/$$"io.writeLine(pattern.replaceAll("a1 b", replacement))io.writeLine(pattern.replaceAll("123", replacement))}case Err(_) => io.writeLine("compile failed")}
a/a1/1//$ b/b///$ 123
Expected result
Expected result
Execution completes. Exit code 0.
a/a1/1//$ b/b///$123
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 576 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 607 - compiler/crates/topaz_product_runtime/src/runtime/call.rs at
912a5e86e1f9· 1019 -
topaz.stdlib.contract.regex-transformatworking-tree - topaz.decision.regex-capture-replacement.1 at
topaz.decisi
Preserve text that is not a braced reference
Linkimport std.regex { Regex }import std.iomatch (Regex.compile("a")) {case Ok(pattern) => io.writeLine(pattern.replaceAll("a", "$word $1 $ $\{\} $\{bad-name\}"))case Err(_) => io.writeLine("compile failed")}
$word $1 $ ${} ${bad-name}
Expected result
Expected result
Execution completes. Exit code 0.
$word $1 $ ${} ${bad-name}
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 576 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 607 - compiler/crates/topaz_product_runtime/src/runtime/call.rs at
912a5e86e1f9· 1019 -
topaz.stdlib.contract.regex-transformatworking-tree - topaz.decision.regex-capture-replacement.1 at
topaz.decisi
Split and replace at each empty-pattern boundary
Linkimport std.regex { Regex }import std.iomatch (Regex.compile("")) {case Ok(pattern) => {for field in (pattern.split("ab")) {io.writeLine("[{field}]")}io.writeLine(pattern.replaceAll("ab", "-"))}case Err(_) => io.writeLine("compile failed")}
[] [a] [b] [] -a-b-
Expected result
Expected result
Execution completes. Exit code 0.
[][a][b][]-a-b-
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 576 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 607 - compiler/crates/topaz_product_runtime/src/runtime/call.rs at
912a5e86e1f9· 1019 -
topaz.stdlib.contract.regex-transformatworking-tree - topaz.decision.regex-capture-replacement.1 at
topaz.decisi
Share the adjacent-empty-match rule across transformations
Linkimport std.regex { Regex }import std.iomatch (Regex.compile("a*")) {case Ok(pattern) => {for field in (pattern.split("ab")) {io.writeLine("[{field}]")}io.writeLine(pattern.replaceAll("ab", "-"))}case Err(_) => io.writeLine("compile failed")}
[] [b] [] -b-
Expected result
Expected result
Execution completes. Exit code 0.
[][b][]-b-
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 576 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 607 - compiler/crates/topaz_product_runtime/src/runtime/call.rs at
912a5e86e1f9· 1019 -
topaz.stdlib.contract.regex-transformatworking-tree - topaz.decision.regex-capture-replacement.1 at
topaz.decisi
Evaluate receiver and replacement inputs once in source order
Linkimport std.regex { Regex }import std.testimport std.iofunction makePattern() -> Regex {io.writeLine("receiver")return test.assertOk(Regex.compile("a"))}function inputText() -> string {io.writeLine("text")return "a"}function replacementText() -> string {io.writeLine("replacement")return "b"}io.writeLine(makePattern().replaceAll(inputText(), replacementText()))
receiver text replacement b
Expected result
Expected result
Execution completes. Exit code 0.
receivertextreplacementb
Source evidence
- compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 576 - compiler/crates/topaz_value/src/value/builtins/path_regex_url.rs at
912a5e86e1f9· 607 - compiler/crates/topaz_product_runtime/src/runtime/call.rs at
912a5e86e1f9· 1019 -
topaz.stdlib.contract.regex-transformatworking-tree - topaz.decision.regex-capture-replacement.1 at
topaz.decisi