| Title: | 'ECMA-262' ('JavaScript') Regular Expressions |
|---|---|
| Description: | Regular expressions with the grammar and the answers of 'ECMA-262', the 'RegExp' of 'JavaScript': every flag, lookbehind, named groups, modifier groups and the Unicode properties, so that a pattern answers in R as it does in a browser or 'Node.js'. Test, match, locate, count, replace and split over character vectors. A pattern without a backreference is matched in time proportional to its size times the text. The engine is the 'corvus-regex-ecma262' 'Rust' crate. |
| Authors: | Matthew Adams [aut, cre], Endjin Limited [cph, fnd] |
| Maintainer: | Matthew Adams <[email protected]> |
| License: | Apache License (>= 2) |
| Version: | 0.2.0 |
| Built: | 2026-10-22 19:25:09 UTC |
| Source: | https://github.com/corvus-dotnet/corvus-regex-ecma262-r |
Regular expressions with the grammar and the answers of ECMA-262, the RegExp of JavaScript, so that a pattern
answers in R as it does in a browser or Node.js. Every flag: d, g, i, m, s,
u, v and y, with the grammar of each; lookbehind, named groups, modifier groups such as
(?i:...), and every Unicode property ECMA-262 lists.
Compile a pattern with ecma_regex, then use it with ecma_test, ecma_match,
ecma_locate, ecma_match_all, ecma_locate_all, ecma_count,
ecma_replace and ecma_split, each over a character vector. Each also takes a pattern as a
string, compiled without flags.
R's strings are matched as UTF-8: one marked as UTF-8, or in the native encoding of a UTF-8 session, is read in place
(after a check that it is UTF-8); one in another encoding is translated. A string marked as bytes is refused. Positions
are in characters from 1, as nchar counts them, an end inclusive, as regexpr gives them.
Without u or v a pattern is matched by UTF-16 code unit, as ECMA-262 matches it, so a match can take
half of a character beyond the Basic Multilingual Plane. Its text then holds that half as U+FFFD, and its positions are
the whole character's.
A pattern that is not valid raises ecma_invalid_pattern; flags that are not, ecma_invalid_flags; a
pattern over a limit of size, ecma_pattern_too_large; a match that reaches its timeout or its cap on
backtracking memory, ecma_match_limit; a string that is not UTF-8 or is marked as bytes,
ecma_encoding_error; and an argument of the wrong kind, ecma_argument_error. All inherit from
ecma_regex_error.
https://github.com/corvus-dotnet/corvus-regex-ecma262-r
For each string, ecma_match_all gives every match of a global search and what each group captured
(matchAll), ecma_locate_all where each match, or one of its groups, starts and ends, and ecma_count how many there are.
After an empty match the search goes on one character later (one code unit without u or v); with the
y flag each match must start where the one before it ended.
ecma_match_all(x, regex) ecma_locate_all(x, regex, group = 0L) ecma_count(x, regex)ecma_match_all(x, regex) ecma_locate_all(x, regex, group = 0L) ecma_count(x, regex)
x |
A character vector. |
regex |
A regular expression from |
group |
The group to locate in each match, by number (0 is the whole match) or by name. |
ecma_match_all returns a list with a character matrix for each string, laid out as ecma_match's
with a row for each match. ecma_locate_all returns a list with an integer matrix for each string, with the
columns start and end (NA for a group that did not take part). Each is NULL for an NA string. ecma_count returns an integer
vector, NA for an NA string; it makes no match, and is the fastest way to know how many there are.
ecma_match_all("1 22 333", "\\d+") ecma_locate_all("x1y22z333", "\\d+") ecma_count(c("a b a", "", NA), "a")ecma_match_all("1 22 333", "\\d+") ecma_locate_all("x1y22z333", "\\d+") ecma_count(c("a b a", "", NA), "a")
ecma_regex compiles a pattern as new RegExp(pattern, flags) does, with a match timeout.
ecma_valid says whether each pattern is valid with the flags, without compiling it.
ecma_set_default_timeout sets the timeout of every pattern compiled without one, and
ecma_default_timeout gives it.
ecma_regex(pattern, flags = "", timeout = NULL) ecma_valid(pattern, flags = "") ecma_set_default_timeout(seconds) ecma_default_timeout() ## S3 method for class 'ecma_regex' print(x, ...) ## S3 method for class 'ecma_regex' format(x, ...)ecma_regex(pattern, flags = "", timeout = NULL) ecma_valid(pattern, flags = "") ecma_set_default_timeout(seconds) ecma_default_timeout() ## S3 method for class 'ecma_regex' print(x, ...) ## S3 method for class 'ecma_regex' format(x, ...)
pattern |
For |
flags |
The flags, such as |
timeout |
The time in seconds each match may take before it is abandoned with |
seconds |
The default timeout in seconds, or |
x |
A compiled regular expression. |
... |
Not used. |
The g flag makes ecma_replace replace every match, and the y flag makes each search match
where it starts. The d flag is accepted and changes nothing, since every match gives its groups' positions.
A pattern has a match timeout, as a Regex of .NET has: every function that matches gives each of its matches
the timeout, and a match that reaches it, or the cap on backtracking memory that comes with it, raises
ecma_match_limit. A pattern compiled without one takes ecma_default_timeout(), which is NULL (no
limit) unless ecma_set_default_timeout set it. Without a timeout a match has no limit of time or of memory, so
give one to a pattern or a text from outside. A pattern given as a string to the other functions takes the default.
A compiled regular expression is not saved with the session: compile it again in a new one.
ecma_regex returns an object of class ecma_regex, with the attributes source, flags (in
the order RegExp gives them), group_count and group_names (the distinct names of the groups, in
the order of the first group of each) and timeout (NULL for none). It is used by every other function,
and from any number of calls. ecma_default_timeout returns the default timeout in seconds, or NULL.
ecma_valid returns a logical vector, NA for an NA pattern.
date <- ecma_regex("(?<year>\\d{4})-(?<month>\\d{2})", "g") date attr(date, "group_names") ecma_valid(c("a+", "a{2,1}", "("), "u") timed <- ecma_regex("^(?:(a+)\\1*)+$", "u", timeout = 0.05) attr(timed, "timeout")date <- ecma_regex("(?<year>\\d{4})-(?<month>\\d{2})", "g") date attr(date, "group_names") ecma_valid(c("a+", "a{2,1}", "("), "u") timed <- ecma_regex("^(?:(a+)\\1*)+$", "u", timeout = 0.05) attr(timed, "timeout")
ecma_replace replaces the first match in each string, or every match when the pattern has the g flag
(String.prototype.replace); ecma_replace_all replaces every match (replaceAll).
ecma_replace(x, regex, replacement) ecma_replace_all(x, regex, replacement)ecma_replace(x, regex, replacement) ecma_replace_all(x, regex, replacement)
x |
A character vector. |
regex |
A regular expression from |
replacement |
A character vector of templates (recycled), or a function. In a template, |
A character vector, NA where the string or its template is NA. A match that takes half of a character
leaves the other half as U+FFFD.
date <- ecma_regex("(?<year>\\d{4})-(?<month>\\d{2})", "g") ecma_replace("2026-10, 2027-01", date, "$<month>/$1") ecma_replace_all("1 2 3", "\\d+", function(m) as.character(as.integer(m[[1]]) * 2))date <- ecma_regex("(?<year>\\d{4})-(?<month>\\d{2})", "g") ecma_replace("2026-10, 2027-01", date, "$<month>/$1") ecma_replace_all("1 2 3", "\\d+", function(m) as.character(as.integer(m[[1]]) * 2))
Splits each string around the matches, as String.prototype.split does: what each group captured is spliced in
after the piece before it, and an empty match at the start or the end of the string splits nothing.
ecma_split(x, regex, limit = NULL)ecma_split(x, regex, limit = NULL)
x |
A character vector. |
regex |
A regular expression from |
limit |
The most pieces to give, or |
A list with a character vector for each string, NA for a group that did not take part, and NULL for an
NA string.
ecma_split("a ; b;c", "\\s*(;)\\s*") ecma_split("a,b", "(x)?,")ecma_split("a ; b;c", "\\s*(;)\\s*") ecma_split("a,b", "(x)?,")
For each string, ecma_test says whether the pattern matches (RegExp.prototype.test),
ecma_match gives the first match and what each group captured (exec), and ecma_locate gives where
the first match, or one of its groups, starts and ends.
ecma_test(x, regex, start = 1L, timeout = NULL) ecma_match(x, regex, start = 1L, timeout = NULL) ecma_locate(x, regex, group = 0L, start = 1L, timeout = NULL)ecma_test(x, regex, start = 1L, timeout = NULL) ecma_match(x, regex, start = 1L, timeout = NULL) ecma_locate(x, regex, group = 0L, start = 1L, timeout = NULL)
x |
A character vector. |
regex |
A regular expression from |
start |
Where each search starts, in characters from 1 (recycled), as |
timeout |
A limit in seconds on the time this match may take in place of the pattern's timeout ( |
group |
The group to locate, by number (0 is the whole match) or by name. |
ecma_test returns a logical vector. ecma_match returns a character matrix with a row for each string:
the match, then each group, then one column for each group name (named by it: of the groups that share a name, the one
that took part). ecma_locate returns an integer matrix with the columns start and end. An empty
match ends one character before it starts. There is NA for an NA string, for a string the pattern does
not match, and for a group that did not take part.
A match that reaches the pattern's timeout (see ecma_regex) or timeout, or the cap on
backtracking memory, raises ecma_match_limit. A pattern
without a backreference is matched in time proportional to its size times the text.
date <- ecma_regex("(?<year>\\d{4})-(?<month>\\d{2})") ecma_test(c("due 2026-10", "none", NA), date) ecma_match("due 2026-10", date) ecma_locate("due 2026-10", date, group = "month") ecma_test(c("foo", "foo"), ecma_regex("o", "y"), start = c(1L, 2L))date <- ecma_regex("(?<year>\\d{4})-(?<month>\\d{2})") ecma_test(c("due 2026-10", "none", NA), date) ecma_match("due 2026-10", date) ecma_locate("due 2026-10", date, group = "month") ecma_test(c("foo", "foo"), ecma_regex("o", "y"), start = c(1L, 2L))
The version of this package's native code and of the corvus-regex-ecma262 crate it was built from.
ecma_version()ecma_version()
A character vector with the elements package and crate.
ecma_version()ecma_version()