当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


R grep 模式匹配和替换


R语言 grep 位于 base 包(package)。

说明

grepgreplregexprgregexprregexecgregexec 在字符向量的每个元素中搜索与参数 pattern 的匹配:它们的格式和详细信息量有所不同结果。

subgsub 分别执行第一个和所有匹配项的替换。

用法

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 (或 fixed = TRUE 的字符串)的字符串。如果可能的话,由 as.character 强制转换为字符串。如果提供长度为 2 或以上的字符向量,则使用第一个元素时会发出警告。除了 regexprgregexprregexec 之外,允许缺少值。

x, text

寻找匹配的字符向量,或可以由 as.character 强制转换为字符向量的对象。支持Long vectors

ignore.case

如果 FALSE ,则模式匹配区分大小写;如果 TRUE ,则在匹配过程中忽略大小写。

perl

合乎逻辑的。应该使用 Perl 兼容的正则表达式吗?

value

如果 FALSE ,则返回包含由 grep 确定的匹配项的 ( integer ) 索引的向量;如果 TRUE ,则返回包含匹配元素本身的向量。

fixed

合乎逻辑的。如果 TRUEpattern 是要按原样匹配的字符串。覆盖所有冲突的参数。

useBytes

合乎逻辑的。如果TRUE 匹配是逐字节完成的,而不是逐字符完成的。查看具体信息'。

invert

合乎逻辑的。如果 TRUE 返回不匹配元素的索引或值。

replacement

替换 subgsub 中的匹配模式。如果可能的话,强制性格。对于 fixed = FALSE ,这可以包括 "\1""\9"pattern 带括号的子表达式的反向引用。仅适用于 perl = TRUE,它还可以包含 "\U""\L" 以将其余替换转换为大写或小写,并包含 "\E" 以结束大小写转换。如果提供长度为 2 或以上的字符向量,则使用第一个元素时会发出警告。如果是 NA ,则匹配结果对应的所有元素都将被设置为 NA

细节

如果可能的话,应该是字符串或字符向量的参数将被强制转换为字符。

这些函数中的每一个都以三种模式之一运行:

  1. fixed = TRUE :使用精确匹配。

  2. perl = TRUE :使用 Perl 风格的正则表达式。

  3. fixed = FALSE, perl = FALSE :使用 POSIX 1003.2 扩展正则表达式(默认)。

有关不同类型正则表达式的详细信息,请参阅regular expression 上的帮助页面。

两个*sub 函数的不同之处仅在于sub 仅替换第一次出现的pattern,而gsub 替换所有出现的gsub。如果 replacement 包含 pattern 中未定义的反向引用,则结果未定义(但大多数情况下反向引用被视为 "" )。

对于 regexprgregexprregexecgregexec 来说,patternNA 是错误的,否则允许 NA 并给出 NA 匹配。

grepgrepl 都将 x 中的缺失值视为不匹配非缺失的 pattern

useBytes = TRUE 的主要作用是避免有关多字节语言环境中的无效输入和虚假匹配的错误/警告,但对于 regexpr 它会更改输出的解释。它禁止带有标记编码的输入的转换,并且如果发现任何标记为 "bytes" 的输入(请参阅 Encoding ),则会强制执行。

无大小写匹配对于多字节语言环境中的字节没有多大意义,并且您应该期望它仅适用于 useBytes = TRUE 的 ASCII 字符。

regexprgregexpr 以及 perl = TRUE 允许 Python 风格的命名捕获,但不适用于长向量输入。

当前语言环境中的无效输入将被警告最多 5 次。

非 ASCII 字符与 perl = TRUE 的无大小写匹配取决于使用“Unicode 属性支持”编译的 PCRE 库,默认情况下 PCRE2 是该库。

grep(value = FALSE)返回元素索引的向量x产生匹配(或不匹配,对于invert = TRUE)。这将是一个整数向量,除非输入是长向量,当它将是双向量时。

grep(value = TRUE) 返回一个字符向量,其中包含 x 的选定元素(强制转换后,保留名称但不保留其他属性)。

grepl 返回一个逻辑向量(x 的每个元素是否匹配)。

subgsub 返回与 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 )导致匹配失败,则这被视为不匹配,通常会出现警告。

警告

gsubgregexpr 的 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 = TRUEuseBytes = FALSE ,优化已经到位,利用了针对 UTF-8 中此类模式的基于字节的匹配。对于 useBytes = TRUE ,字符范围、通配符和其他正则表达式模式可能会产生意外结果。

默认情况下,基于 PCRE 的匹配用于在 ‘studying’ 编译模式中投入额外的精力x/text长度为 10 或更长。该研究可能会在可用的平台上使用 PCRE JIT 编译器(请参阅pcre_config)。从 PCRE2 开始(PCRE 版本 >= 10.00,据报道extSoftVersion),没有学习阶段,但模式会在可能的情况下自动优化,并且在启用时使用 PCRE JIT。细节由控制options PCRE_studyPCRE_use_JIT。 (通过运行文件‘可以看到一些时序比较测试/PCRE.R' 在里面R使用 PCRE 和非常长的字符串的人员可以通过设置环境变量来调整 JIT 堆栈的最大大小R_PCRE_JIT_STACK_MAXSIZE在 JIT 用于之间的值之前11000以 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 用于根据 regexprgregexprregexec 的结果提取匹配的子字符串。

glob2rx 将通配符匹配转换为正则表达式。

agrep 用于近似匹配。

charmatchpmatch 用于部分匹配,match 用于匹配整个字符串,startsWith 用于匹配字符串的初始部分。

tolowertoupperchartr 用于字符翻译。

apropos 使用正则表达式并有更多示例。

grepRaw 用于匹配原始向量。

选项 PCRE_limit_recursionPCRE_studyPCRE_use_JIT

extSoftVersion 了解正在使用的正则表达式和 PCRE 库的版本,pcre_config 了解 PCRE 的更多详细信息。

相关用法


注:本文由纯净天空筛选整理自R-devel大神的英文原创作品 Pattern Matching and Replacement。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。