grep
位于 base
包(package)。 说明
grep
、 grepl
、 regexpr
、 gregexpr
、 regexec
和 gregexec
在字符向量的每个元素中搜索与参数 pattern
的匹配:它们的格式和详细信息量有所不同结果。
sub
和 gsub
分别执行第一个和所有匹配项的替换。
用法
grep(pattern, x, ignore.case = FALSE, perl = FALSE, value = FALSE,
fixed = FALSE, useBytes = FALSE, invert = FALSE)
grepl(pattern, x, ignore.case = FALSE, perl = FALSE,
fixed = FALSE, useBytes = FALSE)
sub(pattern, replacement, x, ignore.case = FALSE, perl = FALSE,
fixed = FALSE, useBytes = FALSE)
gsub(pattern, replacement, x, ignore.case = FALSE, perl = FALSE,
fixed = FALSE, useBytes = FALSE)
regexpr(pattern, text, ignore.case = FALSE, perl = FALSE,
fixed = FALSE, useBytes = FALSE)
gregexpr(pattern, text, ignore.case = FALSE, perl = FALSE,
fixed = FALSE, useBytes = FALSE)
regexec(pattern, text, ignore.case = FALSE, perl = FALSE,
fixed = FALSE, useBytes = FALSE)
gregexec(pattern, text, ignore.case = FALSE, perl = FALSE,
fixed = FALSE, useBytes = FALSE)
参数
pattern |
包含要在给定字符向量中匹配的 regular expression (或 |
x, text |
寻找匹配的字符向量,或可以由 |
ignore.case |
如果 |
perl |
合乎逻辑的。应该使用 Perl 兼容的正则表达式吗? |
value |
如果 |
fixed |
合乎逻辑的。如果 |
useBytes |
合乎逻辑的。如果 |
invert |
合乎逻辑的。如果 |
replacement |
替换 |
细节
如果可能的话,应该是字符串或字符向量的参数将被强制转换为字符。
这些函数中的每一个都以三种模式之一运行:
-
fixed = TRUE
:使用精确匹配。 -
perl = TRUE
:使用 Perl 风格的正则表达式。 -
fixed = FALSE, perl = FALSE
:使用 POSIX 1003.2 扩展正则表达式(默认)。
有关不同类型正则表达式的详细信息,请参阅regular expression 上的帮助页面。
两个*sub
函数的不同之处仅在于sub
仅替换第一次出现的pattern
,而gsub
替换所有出现的gsub
。如果 replacement
包含 pattern
中未定义的反向引用,则结果未定义(但大多数情况下反向引用被视为 ""
)。
对于 regexpr
、 gregexpr
、 regexec
和 gregexec
来说,pattern
为 NA
是错误的,否则允许 NA
并给出 NA
匹配。
grep
和 grepl
都将 x
中的缺失值视为不匹配非缺失的 pattern
。
useBytes = TRUE
的主要作用是避免有关多字节语言环境中的无效输入和虚假匹配的错误/警告,但对于 regexpr
它会更改输出的解释。它禁止带有标记编码的输入的转换,并且如果发现任何标记为 "bytes"
的输入(请参阅 Encoding
),则会强制执行。
无大小写匹配对于多字节语言环境中的字节没有多大意义,并且您应该期望它仅适用于 useBytes = TRUE
的 ASCII 字符。
regexpr
和 gregexpr
以及 perl = TRUE
允许 Python 风格的命名捕获,但不适用于长向量输入。
当前语言环境中的无效输入将被警告最多 5 次。
非 ASCII 字符与 perl = TRUE
的无大小写匹配取决于使用“Unicode 属性支持”编译的 PCRE 库,默认情况下 PCRE2 是该库。
值
grep(value = FALSE)
返回元素索引的向量x
产生匹配(或不匹配,对于invert = TRUE
)。这将是一个整数向量,除非输入是长向量,当它将是双向量时。
grep(value = TRUE)
返回一个字符向量,其中包含 x
的选定元素(强制转换后,保留名称但不保留其他属性)。
grepl
返回一个逻辑向量(x
的每个元素是否匹配)。
sub
和 gsub
返回与 x
具有相同长度和相同属性的字符向量(在可能强制转换为字符之后)。未被替换的字符向量 x
的元素将按原样返回(包括任何声明的编码,如果 useBytes = FALSE
)。如果 useBytes = FALSE
,非 ASCII 替换结果通常是带有标记编码的 UTF-8(例如,如果有 UTF-8 输入,并且在多字节语言环境中,除非 fixed =
TRUE
)。此类字符串可以通过 enc2native
重新编码。如果任何输入标记为 "bytes"
,则被替换的字符向量 x
的元素将返回标记为 "bytes"
,但未指定元素上的编码标志未指定(可能是原始元素或 "bytes")。如果没有任何输入被标记为 "bytes"
,但显式给出了 useBytes = TRUE
,则即使在替换元素上也未指定编码标志(可能是 "bytes"
或 "unknown"
,在当前编码中可能无效)。不鼓励混合使用 "bytes"
和其他标记的编码,但如果仍然需要,可以使用 iconv
重新编码结果,例如转换为 UTF-8,并适当替换无效字节。
regexpr
返回与 text
相同长度的整数向量,给出第一个匹配的起始位置或 (如果没有),属性 "match.length"
是给出匹配文本长度的整数向量(或 表示不匹配)。匹配位置和长度以字符为单位,除非使用 useBytes = TRUE
,否则它们以字节为单位(因为它们仅用于 ASCII 匹配:在任何一种情况下,都会在结果上设置值为 TRUE
的属性 useBytes
)。如果使用命名捕获,则还有更多属性 "capture.start"
、 "capture.length"
和 "capture.names"
。
gregexpr
返回与 text
长度相同的列表,其中每个元素的形式与 regexpr
的返回值相同,只是给出了每个(不相交)匹配的起始位置。
regexec
返回与 text
相同长度的列表,其中每个元素如果没有匹配则为 ,或者是一个整数序列,其中包含匹配的起始位置以及与括号内的子表达式对应的所有子字符串pattern
,属性 "match.length"
是一个给出匹配长度的向量(或 表示不匹配)。位置和长度以及属性的解释遵循 regexpr
。
gregexec
返回与 regexec
相同的结果,除了为了容纳 text
的每个元素的多个匹配项,每个匹配项的整数序列被制成矩阵的列,其中 text
的每个元素有一个匹配的矩阵。
如果由于资源限制(尤其是 perl = TRUE
)导致匹配失败,则这被视为不匹配,通常会出现警告。
警告
gsub
和 gregexpr
的 POSIX 1003.2 模式对于重复的字边界(例如 pattern = "\b"
)无法正常工作。使用 perl = TRUE
进行此类匹配(但对于非 ASCII 输入可能无法按预期工作,因为 ‘word’ 的含义取决于系统)。
性能考虑
如果您正在进行大量正则表达式匹配,包括非常长的字符串,您将需要考虑使用的选项。一般来说,perl = TRUE
会比默认的正则表达式引擎更快,而 fixed = TRUE
仍然更快(特别是当每个模式仅匹配几次时)。
如果您正在处理带有非 ASCII 字符的文本,这些字符可以轻松转换为 ASCII(例如通过替换精美的引号),这样做可能会提高性能。
如果您在单字节语言环境中工作(尽管不常见,因为R4.2) 并且已标记可在该语言环境中表示的 UTF-8 字符串,请首先将它们转换,因为只有一个 UTF-8 字符串将强制所有匹配以 Unicode 完成,这会带来大约 对于默认的 POSIX 1003.2 模式。
虽然 useBytes = TRUE
会进一步提高性能,但由于在匹配之前不会检查字符串,实际匹配速度会更快,因此可能会产生意想不到的结果,因此最好避免。对于 fixed = TRUE
和 useBytes = FALSE
,优化已经到位,利用了针对 UTF-8 中此类模式的基于字节的匹配。对于 useBytes = TRUE
,字符范围、通配符和其他正则表达式模式可能会产生意外结果。
默认情况下,基于 PCRE 的匹配用于在 ‘studying’ 编译模式中投入额外的精力x
/text
长度为 10 或更长。该研究可能会在可用的平台上使用 PCRE JIT 编译器(请参阅pcre_config
)。从 PCRE2 开始(PCRE 版本 >= 10.00,据报道extSoftVersion
),没有学习阶段,但模式会在可能的情况下自动优化,并且在启用时使用 PCRE JIT。细节由控制options
PCRE_study
和PCRE_use_JIT
。 (通过运行文件‘可以看到一些时序比较测试/PCRE.R' 在里面R使用 PCRE 和非常长的字符串的人员可以通过设置环境变量来调整 JIT 堆栈的最大大小R_PCRE_JIT_STACK_MAXSIZE在 JIT 用于之间的值之前1
和1000
以 MB 为单位:默认为64
。当 JIT 不与 PCRE 版本 < 10.30 一起使用时(即 PCRE1 和旧版本的 PCRE2),设置该选项也可能是明智的PCRE_limit_recursion
.
注意
方面将取决于平台以及 locale-dependent:例如字符类的实现([:digit:]
和 [:xdigit:]
除外)。人们可以预期 ASCII 输入和在 UTF-8 模式下工作时的结果是一致的(大多数平台将使用 Unicode 字符表,尽管这些字符表经常更新并且受到某种程度的解释 - 是带圆圈的大写字母还是符号) ?)。然而,8 位编码的结果在不同平台、模式以及 UTF-8 版本之间可能有很大差异。
例子
grep("[a-z]", letters)
txt <- c("arm","foot","lefroo", "bafoobar")
if(length(i <- grep("foo", txt)))
cat("'foo' appears at least once in\n\t", txt, "\n")
i # 2 and 4
txt[i]
## Double all 'a' or 'b's; "\" must be escaped, i.e., 'doubled'
gsub("([ab])", "\\1_\\1_", "abc and ABC")
txt <- c("The", "licenses", "for", "most", "software", "are",
"designed", "to", "take", "away", "your", "freedom",
"to", "share", "and", "change", "it.",
"", "By", "contrast,", "the", "GNU", "General", "Public", "License",
"is", "intended", "to", "guarantee", "your", "freedom", "to",
"share", "and", "change", "free", "software", "--",
"to", "make", "sure", "the", "software", "is",
"free", "for", "all", "its", "users")
( i <- grep("[gu]", txt) ) # indices
stopifnot( txt[i] == grep("[gu]", txt, value = TRUE) )
## Note that for some implementations character ranges are
## locale-dependent (but not currently). Then [b-e] in locales such as
## en_US may include B as the collation order is aAbBcCdDe ...
(ot <- sub("[b-e]",".", txt))
txt[ot != gsub("[b-e]",".", txt)]#- gsub does "global" substitution
## In caseless matching, ranges include both cases:
a <- grep("[b-e]", txt, value = TRUE)
b <- grep("[b-e]", txt, ignore.case = TRUE, value = TRUE)
setdiff(b, a)
txt[gsub("g","#", txt) !=
gsub("g","#", txt, ignore.case = TRUE)] # the "G" words
regexpr("en", txt)
gregexpr("e", txt)
## Using grepl() for filtering
## Find functions with argument names matching "warn":
findArgs <- function(env, pattern) {
nms <- ls(envir = as.environment(env))
nms <- nms[is.na(match(nms, c("F","T")))] # <-- work around "checking hack"
aa <- sapply(nms, function(.) { o <- get(.)
if(is.function(o)) names(formals(o)) })
iw <- sapply(aa, function(a) any(grepl(pattern, a, ignore.case=TRUE)))
aa[iw]
}
findArgs("package:base", "warn")
## trim trailing white space
str <- "Now is the time "
sub(" +$", "", str) ## spaces only
## what is considered 'white space' depends on the locale.
sub("[[:space:]]+$", "", str) ## white space, POSIX-style
## what PCRE considered white space changed in version 8.34: see ?regex
sub("\\s+$", "", str, perl = TRUE) ## PCRE-style white space
## capitalizing
txt <- "a test of capitalizing"
gsub("(\\w)(\\w*)", "\\U\\1\\L\\2", txt, perl=TRUE)
gsub("\\b(\\w)", "\\U\\1", txt, perl=TRUE)
txt2 <- "useRs may fly into JFK or laGuardia"
gsub("(\\w)(\\w*)(\\w)", "\\U\\1\\E\\2\\U\\3", txt2, perl=TRUE)
sub("(\\w)(\\w*)(\\w)", "\\U\\1\\E\\2\\U\\3", txt2, perl=TRUE)
## named capture
notables <- c(" Ben Franklin and Jefferson Davis",
"\tMillard Fillmore")
# name groups 'first' and 'last'
name.rex <- "(?<first>[[:upper:]][[:lower:]]+) (?<last>[[:upper:]][[:lower:]]+)"
(parsed <- regexpr(name.rex, notables, perl = TRUE))
gregexpr(name.rex, notables, perl = TRUE)[[2]]
parse.one <- function(res, result) {
m <- do.call(rbind, lapply(seq_along(res), function(i) {
if(result[i] == -1) return("")
st <- attr(result, "capture.start")[i, ]
substring(res[i], st, st + attr(result, "capture.length")[i, ] - 1)
}))
colnames(m) <- attr(result, "capture.names")
m
}
parse.one(notables, parsed)
## Decompose a URL into its components.
## Example by LT (http://www.cs.uiowa.edu/~luke/R/regexp.html).
x <- "http://stat.umn.edu:80/xyz"
m <- regexec("^(([^:]+)://)?([^:/]+)(:([0-9]+))?(/.*)", x)
m
regmatches(x, m)
## Element 3 is the protocol, 4 is the host, 6 is the port, and 7
## is the path. We can use this to make a function for extracting the
## parts of a URL:
URL_parts <- function(x) {
m <- regexec("^(([^:]+)://)?([^:/]+)(:([0-9]+))?(/.*)", x)
parts <- do.call(rbind,
lapply(regmatches(x, m), `[`, c(3L, 4L, 6L, 7L)))
colnames(parts) <- c("protocol","host","port","path")
parts
}
URL_parts(x)
## gregexec() may match multiple times within a single string.
pattern <- "([[:alpha:]]+)([[:digit:]]+)"
s <- "Test: A1 BC23 DEF456"
m <- gregexec(pattern, s)
m
regmatches(s, m)
## Before gregexec() was implemented, one could emulate it by running
## regexec() on the regmatches obtained via gregexpr(). E.g.:
lapply(regmatches(s, gregexpr(pattern, s)),
function(e) regmatches(e, regexec(pattern, e)))
来源
POSIX 风格正则表达式匹配的 C 代码多年来已经发生了变化。来自R2.10.0(2009 年 10 月)Ville Laurikari 的 TRE Library (https://github.com/laurikari/tre) 用来。 POSIX 标准确实提供了一些解释空间,特别是在处理无效正则表达式和字符范围排序规则方面,因此多年来结果会略有变化。
对于 Perl 风格的匹配,使用 PCRE2 或 PCRE ( https://www.pcre.org ):同样,结果可能(稍微)取决于所使用的 PCRE 版本。
参考
Becker, R. A., Chambers, J. M. and Wilks, A. R. (1988)
The New S Language.
Wadsworth & Brooks/Cole (grep
)
也可以看看
regular expression(又名regexp
)了解模式规范的详细信息。
regmatches
用于根据 regexpr
、 gregexpr
和 regexec
的结果提取匹配的子字符串。
glob2rx
将通配符匹配转换为正则表达式。
agrep
用于近似匹配。
charmatch
、 pmatch
用于部分匹配,match
用于匹配整个字符串,startsWith
用于匹配字符串的初始部分。
tolower
、 toupper
和 chartr
用于字符翻译。
apropos
使用正则表达式并有更多示例。
grepRaw
用于匹配原始向量。
选项 PCRE_limit_recursion
、 PCRE_study
和 PCRE_use_JIT
。
extSoftVersion
了解正在使用的正则表达式和 PCRE 库的版本,pcre_config
了解 PCRE 的更多详细信息。
相关用法
- R grepRaw 原始向量的模式匹配
- R groupGeneric S3组通用函数
- R grouping 分组排列
- R getwd 获取或设置工作目录
- R getDLLRegisteredRoutines DLL 中 C/Fortran 例程的反射信息
- R gzcon 通过连接(解)压缩 I/O
- R get 返回命名对象的值
- R gc 垃圾收集
- R gl 生成因子水平
- R getLoadedDLLs 获取当前会话中加载的 DLL
- R gc.time 报告垃圾收集所花费的时间
- R gettext 翻译短信
- R gctorture 酷刑垃圾收集者
- R getNativeSymbolInfo 获取一个或多个本机 (C/Fortran) 符号的说明
- R file.path 构造文件路径
- R vector 向量 - 创建、强制等
- R lapply 对列表或向量应用函数
- R dump R 对象的文本表示
- R Sys.getenv 获取环境变量
- R rank 样本排名
- R pushBack 将文本推回连接
- R strsplit 分割字符向量的元素
- R seq.Date 生成规则的日期序列
- R invisible 将打印模式更改为不可见
- R noquote “无引号”字符串打印类
注:本文由纯净天空筛选整理自R-devel大神的英文原创作品 Pattern Matching and Replacement。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。