DBDelve
Dive deep into your data. A fast, native, multi-engine database client written in Rust. Free and open source, no telemetry.
翻译准备中
Matches regular expressions with a bundled copy of the PCRE2 library (<https://github.com/PCRE2Project/pcre2>), so that every platform runs the same version with its just-in-time compiler. Patterns ar
翻译准备中
开发工具R · CGitHub @pedrobtz运行状态需重新检查运营者未确认
试用过了吗? 点一下就好,无需登录。
尚未检测到更新。GitHub 发布版本后会显示在这里。
Matches regular expressions with a bundled copy of the PCRE2 library (<https://github.com/PCRE2Project/pcre2>), so that every platform runs the same version with its just-in-time compiler. Patterns are compiled once and cached, matching runs on several threads, and capture groups are returned as character vectors and data frames built in C. Replacements use the full PCRE2 substitution language, and each call can bound its work with match, depth and heap limits. Other packages reach the same libr
翻译准备中
正在加载完整 README。
查看完整 README ↗Base R already matches regular expressions with
PCRE2 when you ask for
perl = TRUE. But it compiles the pattern again on every call, matches
on one thread, hands back capture groups as attributes you have to take
apart, and knows only \\1 to \\9 in replacements. A package that
needs PCRE2 from C has to bundle its own copy, as vectorscan does.
zuregex bundles one PCRE2, the same version on every platform, and
builds on it twice: as re_*() functions for R, and as a C API other
packages reach through LinkingTo.
re_match() returns a data frame with a column
per group, built in C, and can type the columns as
utils::strcapture() does.NA instead of a stall.Install zuregex from CRAN with:
install.packages("zuregex")
Or install the development version from GitHub with:
# install.packages("pak")
pak::pak("pedrobtz/zuregex")
library(zuregex)
Take a few lines from a web server’s log.
log <- c(
"2026-10-21 08:15:02 GET /index.html 200 512",
"2026-10-21 08:15:09 POST /login 302 0",
"2026-10-21 08:16:44 GET /missing 404 128",
"not a log line"
)
re_detect() and re_count() work as grepl() and
stringr::str_count() do, element by element.
re_detect(log, "\\s(?:GET|POST)\\s")
#> [1] TRUE TRUE TRUE FALSE
re_count(log, "\\d+")
#> [1] 8 8 8 0
re_match() turns named groups into columns. A line that does not match
is a row of NA. proto gives the columns types, here an integer
status.
pattern <- "(?<time>\\S+ \\S+) (?<method>[A-Z]+) (?<path>\\S+) (?<status>\\d+)"
re_match(log, pattern)
#> time method path status
#> 1 2026-10-21 08:15:02 GET /index.html 200
#> 2 2026-10-21 08:15:09 POST /login 302
#> 3 2026-10-21 08:16:44 GET /missing 404
#> 4 <NA> <NA> <NA> <NA>
typed <- re_match(
log,
pattern,
proto = data.frame(time = "", method = "", path = "", status = 0L)
)
str(typed)
#> 'data.frame': 4 obs. of 4 variables:
#> $ time : chr "2026-10-21 08:15:02" "2026-10-21 08:15:09" "2026-10-21 08:16:44" NA
#> $ method: chr "GET" "POST" "GET" NA
#> $ path : chr "/index.html" "/login" "/missing" NA
#> $ status: int 200 302 404 NA
Replacements use PCRE2’s templates: ${name} for a named group, and
${n:-default} for a group that may not take part.
re_replace(log, "^(?<y>\\d+)-(?<m>\\d+)-(?<d>\\d+)", "${d}/${m}/${y}")
#> [1] "21/10/2026 08:15:02 GET /index.html 200 512"
#> [2] "21/10/2026 08:15:09 POST /login 302 0"
#> [3] "21/10/2026 08:16:44 GET /missing 404 128"
#> [4] "not a log line"
re_replace(c("v1.2", "v3"), "v(\\d+)(?:\\.(\\d+))?", "major $1, minor ${2:-0}")
#> [1] "major 1, minor 2" "major 3, minor 0"
A function works too. It is called once, with a data frame of every match.
re_replace(log, "/\\w+", function(m) toupper(m[["0"]]))
#> [1] "2026-10-21 08:15:02 GET /INDEX.html 200 512"
#> [2] "2026-10-21 08:15:09 POST /LOGIN 302 0"
#> [3] "2026-10-21 08:16:44 GET /MISSING 404 128"
#> [4] "not a log line"
re_compile() sets flags once:
re_detect(c("Hello", "hello"), re_compile("HELLO", flags = "i"))
#> [1] TRUE TRUE
and re_limits() bounds the work. ^(a+)+$ backtracks exponentially on
a long run of a that ends in something else. With a limit, that
element stops early and gives NA, with one warning for the call.
re_detect(
c(paste0(strrep("a", 30), "!"), "aaa"),
"^(a+)+$",
limits = re_limits(match = 1e4, on_limit = "na")
)
#> Warning in re_detect(c(paste0(strrep("a", 30), "!"), "aaa"), "^(a+)+$", : 1
#> element of `x` hit a match limit and is `NA`.
#> [1] NA TRUE
Every function follows the same pattern: x first, then pattern,
which is one pattern for every element or one per element, never
recycled.
Packages that need PCRE2 from C add zuregex to Imports and
LinkingTo and include <zuregex-r.h>, instead of bundling their own
copy. Patterns and match data are opaque handles, so an upgrade of the
bundled PCRE2 never changes a consumer’s build. The header documents the
API.
?re_compile has the flag letters, ?re_replace the template syntax,
and ?re_limits what limits can and cannot promise.zuregex bundles PCRE2 and
checks itself against PCRE2’s own test results, base R’s perl = TRUE
and stringr. Its API borrows from
Python’s pcre2.py,
JavaScript’s node-pcre2 and
Go’s go-re2. For matching in
linear time, which PCRE2 cannot promise, use
re2.