當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。