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