StringExtract¶
Status: Stable
documented, exercised by the test suite and/or worked examples, with no known limitations recorded.
Description¶
StringExtract["string", n]
Extracts the nth whitespace-delimited block of "string" (-n counts from the end).
StringExtract["string", spec]
Selects blocks with spec: n, -n, {n1, n2, ...}, n1;;n2, or All.
StringExtract["string", sep -> pos]
Delimits blocks with the string pattern sep. sep -> All equals StringSplit["string", sep].
StringExtract["string", pos1, pos2, ...]
Extracts across levels: whitespace at the lowest level, then "\n", then "\n\n", and so on for higher levels.
StringExtract["string", sep1 -> pos1, sep2 -> pos2, ...]
Uses sepi as the separator for successive levels. Absent blocks yield Missing["PartAbsent", pos]. A list of strings threads.
Examples (7)¶
Every input below was run against the current Mathilda build and its output recorded.
Basic examples (4)¶
In[1]:= StringExtract["a bbb cccc aa d", 2]
Out[1]= "bbb"
In[2]:= StringExtract["a bbb cccc aa d", 2 ;; 4]
Out[2]= {"bbb", "cccc", "aa"}
In[3]:= StringExtract["a--bbb--ccc--dddd", "--" -> 3]
Out[3]= "ccc"
In[4]:= StringExtract["a 1\nb 2\nc 3 x", All, 3]
Out[4]= {Missing["PartAbsent", 3], Missing["PartAbsent", 3], "x"}
Applications (3)¶
The 2nd whitespace-delimited block
Split on "-", take the 3rd block
A span of blocks
Algorithm¶
stringextract.c - StringExtract[subject, spec_1, ..., spec_k]
Splits a string into blocks and selects blocks by position. Each spec_j is a level: either a bare position (n, -n, {n1,...}, n1;;n2, All) or a rule
pos_j; if more levels remain it recurses into each selected block.
The split is delegated to StringSplit (built here as StringSplit[str, sep] and evaluated), so the entire WL string-pattern engine, whitespace-run collapsing, and empty-end trimming are reused verbatim. This makes the documented equivalences exact:
StringExtract[s, patt -> All] == StringSplit[s, patt]
StringExtract[s, {p1, p2, ...}] == Part[StringSplit[s], {p1, p2, ...}]
Bare positions get depth-default separators: the last (lowest) level splits on whitespace, the level above on a single "\n", the next on "\n\n", and so on. An out-of-range single index yields Missing["PartAbsent", n] (matching Wolfram and the Missing["KeyAbsent", ...] convention in part.c), not the usual NULL-unevaluated result.
Registered by regex_init() (regex_init.c) alongside its StringSplit dependency. Docstring lives in info.c. Attribute: Protected.
Implementation notes¶
Algorithm. builtin_stringextract splits a string into blocks and selects by position, treating each argument after the subject as one level (fewer than two arguments emits StringExtract::argm). The split at every level is delegated to StringSplit (synthesised as StringSplit[str, sep] and evaluated), so the whole string-pattern engine, whitespace-run collapsing, and empty-end trimming are reused verbatim ā making StringExtract[s, sep -> All] exactly StringSplit[s, sep]. apply_position resolves n/-n (pos_single), All (every block), {nā¦} (a collection, deferring any Span/All element to Part semantics), and m ;; n (a Span, via expr_part). An explicit sep -> pos rule carries its own separator; a bare position gets a depth-default separator ā whitespace at the lowest level, growing runs of "\n" above. Multi-level specs recurse into each selected block.
Data structures. A LevelSpec table of borrowed-or-owned separator/position pairs; results nest as Lists.
Complexity / limits. Dominated by the delegated StringSplit evaluations. An out-of-range single index yields Missing["PartAbsent", n] rather than leaving the call unevaluated; a non-string subject (or list element) does leave it unevaluated. A list subject threads.
Attributes: Protected.
References¶
See also: StringSplit
- Source:
src/strings/stringextract.c - Specification:
docs/spec/builtins/string-operations.md - Tests:
tests/test_string_review.c - Tests:
tests/test_stringfns.c
Notes & additional examples¶
Notes¶
StringExtract splits a string into blocks and selects by position. It is built
directly on StringSplit (it synthesises and evaluates StringSplit[str, sep]),
so the split behaviour is identical and StringExtract[s, sep -> All] is exactly
StringSplit[s, sep].
A bare position gets a depth-default separator (whitespace at the lowest level,
growing runs of "\n" above). An out-of-range index yields
Missing["PartAbsent", n] rather than leaving the call unevaluated.