Capture operations are available from
regexp; no separate vocabulary is needed.
first-match-with-captures ( string regexp -- match/f )
all-matches-with-captures ( string regexp -- matches )
capture ( group match -- slice/f )
capture-bounds ( group match -- from/f to/f )
regexp-match
Ordinary parentheses capture;
(?:...) groups without capturing. Groups are numbered from one in opening-parenthesis order, including groups in alternatives that do not participate and groups repeated zero times. Group zero is the whole match. A named group, written
(?<name>...), also has a number. Names consist of ASCII letters, digits and underscores, with a letter or underscore first. Names must be unique within the expression.
Each group is a slice of the original input, or
f if it did not participate. An empty capture is an empty slice. The
groups>> accessor returns the array of groups;
capture selects a group by number or name. Slice offsets are zero-based character indices in the original input, with an exclusive end. Use
capture-bounds to retrieve both offsets; group zero gives the whole match bounds. Converting a slice with
>string discards its original offsets.
USING: prettyprint regexp strings ;
"2026-09" R/ (?<year>\d{4})-(\d{2})/ first-match-with-captures
"year" swap capture >string .
"2026"
Match selectionThe whole match is exactly the one chosen by
first-match or
all-matching-slices, including leftmost-longest selection and reversed searches. Within that fixed span, captures prefer earlier alternatives and greedy repetitions. For example, matching
(a|aa)(a?) against
aa captures
a in both groups. This is not POSIX longest-subexpression disambiguation. Reluctant quantifier spellings retain Factor's existing greedy behavior.
A repeated group retains its last participating capture. Inner groups that do not participate in a later repetition retain their previous capture. Empty loops are cut off when they revisit the same automaton state at the same input position. Group numbering and capture extraction proceed left to right even for reversed searches.
Lookaround and complementPositive lookaround can capture outside the whole match. It chooses the longest matching lookahead or lookbehind span, then resolves captures within that span using the same rules. Anchors and boundaries refer to the original input. Groups inside negative lookaround or a complemented expression
(?~...) retain their numbers but do not participate, so their values are
f.
ExecutionThe existing DFA chooses each whole match. A separate ordered NFA pass records captures only when requested, and its compiled program is cached on the regular expression. Capture registers belong to each call. Without lookaround, the pass visits each state at most once per input position, avoiding exponential backtracking. Lookaround adds nested matching work. Backreferences remain unsupported.