Rev 85065 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
% File src/library/base/man/regmatches.Rd% Part of the R package, https://www.R-project.org% Copyright 1995-2014 R Core Team% Distributed under GPL 2 or later\name{regmatches}\alias{regmatches}\alias{regmatches<-}\title{Extract or Replace Matched Substrings}\description{Extract or replace matched substrings from match data obtained by\code{\link{regexpr}}, \code{\link{gregexpr}},\code{\link{regexec}} or \code{\link{gregexec}}.}\usage{regmatches(x, m, invert = FALSE)regmatches(x, m, invert = FALSE) <- value}\arguments{\item{x}{a character vector.}\item{m}{an object with match data.}\item{invert}{a logical: if \code{TRUE}, extract or replace thenon-matched substrings.}\item{value}{an object with suitable replacement values for thematched or non-matched substrings (see \code{Details}).}}\details{If \code{invert} is \code{FALSE} (default), \code{regmatches} extractsthe matched substrings as specified by the match data. For vectormatch data (as obtained from \code{\link{regexpr}}), empty matches aredropped; for list match data, empty matches give empty components(zero-length character vectors).If \code{invert} is \code{TRUE}, \code{regmatches} extracts thenon-matched substrings, i.e., the strings are split according to thematches similar to \code{\link{strsplit}} (for vector match data, atmost a single split is performed).If \code{invert} is \code{NA}, \code{regmatches} extracts bothnon-matched and matched substrings, always starting and ending with anon-match (empty if the match occurred at the beginning or the end,respectively).Note that the match data can be obtained from regular expressionmatching on a modified version of \code{x} with the same numbers ofcharacters.The replacement function can be used for replacing the matched ornon-matched substrings. For vector match data, if \code{invert} is\code{FALSE}, \code{value} should be a character vector with length thenumber of matched elements in \code{m}. Otherwise, it should be alist of character vectors with the same length as \code{m}, each aslong as the number of replacements needed. Replacement coerces valuesto character or list and generously recycles values as needed.Missing replacement values are not allowed.}\value{For \code{regmatches}, a character vector with the matched substringsif \code{m} is a vector and \code{invert} is \code{FALSE}. Otherwise,a list with the matched or/and non-matched substrings.For \code{regmatches<-}, the updated character vector.}\examples{x <- c("A and B", "A, B and C", "A, B, C and D", "foobar")pattern <- "[[:space:]]*(,|and)[[:space:]]"## Match data from regexpr()m <- regexpr(pattern, x)regmatches(x, m)regmatches(x, m, invert = TRUE)## Match data from gregexpr()m <- gregexpr(pattern, x)regmatches(x, m)regmatches(x, m, invert = TRUE)## Considerx <- "John (fishing, hunting), Paul (hiking, biking)"## Suppose we want to split at the comma (plus spaces) between the## persons, but not at the commas in the parenthesized hobby lists.## One idea is to "blank out" the parenthesized parts to match the## parts to be used for splitting, and extract the persons as the## non-matched parts.## First, match the parenthesized hobby lists.m <- gregexpr("\\\\([^)]*\\\\)", x)## Create blank strings with given numbers of characters.blanks <- function(n) strrep(" ", n)## Create a copy of x with the parenthesized parts blanked out.s <- xregmatches(s, m) <- Map(blanks, lapply(regmatches(s, m), nchar))s## Compute the positions of the split matches (note that we cannot call## strsplit() on x with match data from s).m <- gregexpr(", *", s)## And finally extract the non-matched parts.regmatches(x, m, invert = TRUE)## regexec() and gregexec() return overlapping ranges because the## first match is the full match. This conflicts with regmatches()<-## and regmatches(..., invert=TRUE). We can work-around by dropping## the first match.drop_first <- function(x) {if(!anyNA(x) && all(x > 0)) {ml <- attr(x, 'match.length')if(is.matrix(x)) x <- x[-1,] else x <- x[-1]attr(x, 'match.length') <- if(is.matrix(ml)) ml[-1,] else ml[-1]}x}m <- gregexec("(\\\\w+) \\\\(((?:\\\\w+(?:, )?)+)\\\\)", x)regmatches(x, m)try(regmatches(x, m, invert=TRUE))regmatches(x, lapply(m, drop_first))## invert=TRUE loses matrix structure because we are retrieving what## is in between every sub-matchregmatches(x, lapply(m, drop_first), invert=TRUE)y <- z <- x## Notice **list**(...) on the RHSregmatches(y, lapply(m, drop_first)) <- list(c("<NAME>", "<HOBBY-LIST>"))yregmatches(z, lapply(m, drop_first), invert=TRUE) <-list(sprintf("<\%d>", 1:5))z## With `perl = TRUE` and `invert = FALSE` capture group names## are preserved. Collect functions and arguments in calls:NEWS <- head(readLines(file.path(R.home("doc"), "NEWS.2")), 100)m <- gregexec("(?<fun>\\\\w+)\\\\((?<args>[^)]*)\\\\)", NEWS, perl = TRUE)y <- regmatches(NEWS, m)y[[16]]## Make tabular, adding original line numbersmdat <- as.data.frame(t(do.call(cbind, y)))mdat <- cbind(mdat, line=rep(seq_along(y), lengths(y) / ncol(mdat)))head(mdat)NEWS[head(mdat[['line']])]}\keyword{character}\keyword{utilities}