Extracts the query component of a URL, optionally parsing it into a list.
Usage
get_query(
url,
protocol_handling = "keep",
format = c("string", "list"),
decode = TRUE,
query_handling = c("keep", "drop", "filter", "allow"),
params_keep = NULL,
params_drop = NULL,
params_case_sensitive = FALSE,
sort_params = FALSE,
empty_param_handling = c("keep", "drop"),
decode_plus = FALSE,
scheme_policy = c("infer", "require"),
scheme_acceptance = c("web", "general"),
url_standard = NULL
)Arguments
- url
A character vector of URLs.
- protocol_handling
A character string specifying how to handle protocols. Defaults to "keep". Regardless of this option, rurl only processes authority-based URLs whose scheme is one of http, https, ftp, or ftps; a scheme-bearing input with any other scheme (e.g.
mailto:,tel:,ws:) yieldsparse_status = "error". Scheme inference (below) also requires the input to be host-shaped: a scheme-less string that is not a host (e.g."asdfghjkl","12345","/path") or is a non-canonical IP literal (integer/hex/octal/short forms, or leading-zero octets like"192.168.010.1") is rejected as"error"rather than having a scheme fabricated for it."keep": If a supported scheme exists (http, https, ftp, ftps), it's used. If no scheme and the input is host-shaped, "http://" is added; otherwise the input is not a URL and yields
"error"."none": If a supported scheme exists, it's used. If no scheme, then no scheme is used (scheme component will be NA).
"strip": Any existing scheme is removed (scheme component will be NA).
"http": The scheme is forced to be "http".
"https": The scheme is forced to be "https".
- format
Return format: "string" (default) or "list" for parsed elements.
- decode
Logical; if TRUE (default), percent-decodes the query (the whole string for format="string", keys/values for format="list"). Set FALSE to obtain the query as written: the raw query for the default
query_handling = "keep", or the canonical re-encoded form (uppercase hex,%20,%26/%3D) once any filtering is requested.- query_handling
A character string controlling whether (and how) the query string is included in
clean_url. Defaults to "drop", which preserves the historical query-freeclean_url. The rawqueryresult field is never affected by this option — it always reports the faithful original query."drop": (Default)
clean_urlcarries no query, exactly as before."filter": Keep contentful params, dropping known trackers via a built-in denylist (e.g.
utm_*,fbclid,gclid).params_dropextends the denylist;params_keeprescues names (winning over both the denylist and empty-dropping)."allow": Keep only params whose names match
params_keep; all others are dropped. Hereparams_keepis an inclusion criterion only, not an empty-rescue."keep": Keep every param, re-encoded into canonical form (not the verbatim original — that stays on the
queryfield).
In every non-"drop" mode the surviving query is re-encoded canonically (uppercase percent-hex, spaces as
%20) and appended after the path. The query is intentionally EXEMPT fromcase_handling(query values are case-sensitive — tokens, IDs, signatures), so undercase_handling = "lower"or"upper"theclean_urlis no longer uniformly cased: scheme/host/path fold but the query keeps its original case. Becauseclean_urlis thecanonical_joinkey, any non-"drop" mode also brings the query into that join key (so?id=1and?id=2stop collapsing, whileutm-only differences still collapse under "filter").- params_keep
Character vector of parameter-name globs (only
*is special), orNULL(default). In "filter" mode this is the rescue list; in "allow" mode it is the allowlist. Ignored in "drop"/"keep".- params_drop
Character vector of parameter-name globs to add to the built-in denylist in "filter" mode, or
NULL(default). Ignored in "drop"/"allow"/"keep".- params_case_sensitive
Logical (default
FALSE). Controls whether the denylist andparams_keep/params_dropmatching is case-sensitive.- sort_params
Logical (default
FALSE). WhenTRUE, surviving params are stably sorted by decoded key. Active in "filter"/"allow"/"keep".- empty_param_handling
One of "keep" (default) or "drop". "drop" removes empty-valued params (e.g.
?ref=), except those rescued byparams_keepin "filter" mode.- decode_plus
Logical (default
FALSE). WhenTRUE,+in query values is treated as a space (HTML-form decoding) before percent-decoding.FALSEkeeps+literal (RFC 3986 generic behavior).- scheme_policy
Controls whether scheme-less, host-shaped input is accepted (an input-acceptance axis, distinct from
protocol_handling, which only controls how the scheme is presented, and fromurl_standard, which controls interpretation). Defaults to "infer"."infer": (Default) Fabricate
http://for scheme-less host-shaped input (e.g.example.comparses ashttp://example.com), a browser-omnibox-style affordance. This is the historical behavior."require": Reject scheme-less input — a scheme-less host-shaped value becomes
parse_status = "error"rather than gaining a fabricated scheme. Use this for a strict, pure-parser posture. Note this governs only bare host input; scheme-relative//hostinput is governed separately byscheme_relative_handling.
- scheme_acceptance
Which scheme tokens may enter parsing (a scheme-acceptance axis, distinct from
scheme_policy, which governs scheme-less input, and fromurl_standard, which governs interpretation). Defaults to "web"."web": (Default) Only the curated web-scheme allowlist (
http/https/ftp/ftps/file) is admitted; a scheme-bearing input outside it isparse_status = "error". This is the historical, byte-for-byte compatible behavior."general": Admit any syntactically valid scheme token and parse opaque (
mailto:x), non-special (foo://host), and RFC-generic URLs. Requires an expliciturl_standard("rfc3986"or"whatwg"), which decides the interpretation;generalwithurl_standard = NULLis an error. Non-special / opaque hosts receive no www-stripping, no domain/TLD derivation, and are never run through the IDNA/punycode helpers. A non-special scheme with no//is an opaque path: it has no authority, sohost,user,portand thedomain/tldcolumns are allNAand the entire remainder is thepath(query/fragmentare still split off). This includesmailto:— the recipient's@never re-triggers authority parsing. To decompose amailto:recipient, use the accessors (get_host()/get_domain()/get_user(), ADR 0012 D7) orget_mailto_recipients(); those deliberately return a recipient's parts where this table presentsNA, because a recipient domain is extraction metadata, not the URL's authority.
- url_standard
Optional top-level standard profile:
NULL(default),"rfc3986", or"whatwg". WithNULLthe behavior is exactly what the individual low-level options select (fully backward compatible). When set, it selects a coherent set of standard-conformant behaviors for the axes it governs — path percent/dot handling, the host IPv4/reg-name model, andcase_handling— so callers do not have to hand-assemble the low-level knobs. Passing a governed low-level knob (path_normalizationorcase_handling) with a value the selected profile would not choose is an error; passing the value the profile would pick is accepted (onlycase_handling = "lower_host"is accepted under a selector —"keep","lower", and"upper"all conflict, since"lower"also lowercases the path, which neither standard sanctions). Added as the last argument so existing positional calls keep their meaning; always pass it by name. Under"whatwg"the selector additionally recognizes a literal backslash as a path separator for WHATWG-special schemes (http/https/ftp) and nulls default ports in parse output; useport_handling = "strip_default"for spec-style clean URL port rendering. Seeresolve_urlforurl_standard-governed reference resolution. The selector does not govern whetherport_handlingmay be set (it is a standalone editorial knob), nor does it governpath_encoding(an orthogonal path-presentation knob that layers on any profile), IDNA rendering, or query handling.
Details
The underlying parse preserves the raw query string byte-for-byte (a bare
key such as ?flag stays flag, not flag=). By default this accessor
still percent-decodes for readability (decode = TRUE); pass
decode = FALSE to obtain the raw query exactly as written in the URL.
Under url_standard = "whatwg" the underlying query carries the standard's
percent-encoded spelling (the query percent-encode set is applied, so a
literal space becomes %20); under url_standard = "rfc3986" or no
selector it is the raw source spelling. That distinction is only visible
with decode = FALSE, since decoding collapses both spellings.
The filtering arguments (query_handling, params_keep, params_drop,
params_case_sensitive, sort_params, empty_param_handling,
decode_plus) share the engine used by get_clean_url, but
default to query_handling = "keep" here: an accessor returns the query as
found unless you ask it to filter. When no filtering or reordering is
requested (the default profile), the output is byte-for-byte identical to
earlier releases; once you opt in, the surviving params are selected first
and only then rendered per format/decode.
Examples
get_query("http://example.com/path?a=1&b=2")
#> [1] "a=1&b=2"
get_query("http://example.com/path?a=1&b=2", format = "list")
#> [[1]]
#> [[1]]$a
#> [1] "1"
#>
#> [[1]]$b
#> [1] "2"
#>
#>
# Drop trackers, keep contentful params:
get_query(
"http://example.com/?utm_source=nl&id=42",
query_handling = "filter"
)
#> [1] "id=42"
# Canonical (re-encoded) form:
get_query(
"http://example.com/?a=1%262",
query_handling = "keep", decode = FALSE
)
#> [1] "a=1%262"