[英]How can I use grep with parameters in R?
顯然我不明白 grep 在 R 中的工作方式。如果我在我的 OS X 終端上使用 grep,我可以使用參數 -o 這使得 grep 只返回匹配的部分。 在 R 中,我找不到如何做相應的事情。 閱讀手冊我認為 values 是正確的方法,因為它返回字符而不是索引,但仍然返回整個字符串,所以更好。
# some string fasdjlk465öfsdj123
# R
test <- fasdjlk465öfsdj123
grep("[0-9]",test,value=TRUE) # returns "fasdjlk465öfsdj123"
# shell
grep -o '[0-9]' fasdjlk465öfsdj123
# returns 4 6 5 1 2 3
我在 R 中缺少的參數是什么?
編輯:Joris Meys 的建議非常接近我想要做的。 作為 readLines 的結果,我得到了一個向量。 我想檢查向量的每個元素的數字並返回這些數字。 我真的很驚訝沒有標准的解決方案。 我想過使用一些處理字符串的 regexp 函數並返回像 grep -o 這樣的匹配項,然后在該向量上使用 lapply 。 grep.custom 最接近——我會盡力讓它對我有用。
Spacedman 已經說過了。 如果你真的想在 shell 中模擬 grep,你必須使用strsplit()
字符本身:
> chartest <- unlist(strsplit(test,""))
> chartest
[1] "f" "a" "s" "d" "j" "l" "k" "4" "6" "5" "ö" "f" "s" "d" "j" "1" "2" "3"
> grep("[0-9]",chartest,value=T)
[1] "4" "6" "5" "1" "2" "3"
編輯 :
正如 Nico 所說,如果您想對完整的正則表達式執行此操作,則需要使用gregexpr()
和substr()
。 我會做一個這樣的自定義函數:
grep.custom <- function(x,pattern){
strt <- gregexpr(pattern,x)[[1]]
lngth <- attributes(strt)$match.length
stp <- strt + lngth - 1
apply(cbind(strt,stp),1,function(i){substr(x,i[1],i[2])})
}
然后 :
> grep.custom(test,"sd")
[1] "sd" "sd"
> grep.custom(test,"[0-9]")
[1] "4" "6" "5" "1" "2" "3"
> grep.custom(test,"[a-z]s[a-z]")
[1] "asd" "fsd"
編輯2:
對於向量,使用函數Vectorize()
,例如:
> X <- c("sq25dfgj","sqd265jfm","qs55d26fjm" )
> v.grep.custom <- Vectorize(grep.custom)
> v.grep.custom(X,"[0-9]+")
$sq25dfgj
[1] "25"
$sqd265jfm
[1] "265"
$qs55d26fjm
[1] "55" "26"
如果您想從 shell 調用 grep,請參閱?system
那是因為 R 的 'grep' 適用於向量 - 它會搜索每個元素並返回匹配的元素索引。 它說“這個向量中的哪些元素匹配這個模式?” 例如,這里我們制作了一個 3 的向量,然后問“這個向量中的哪些元素有一個單一的數字?”
> test = c("fasdjlk465öfsdj123","nonumbers","123")
> grep("[0-9]",test)
[1] 1 3
元素 1 和 3 - 不是 2,它只是字符。
你可能想要 gsub - 用任何東西替換任何與數字不匹配的東西:
> gsub("[^0-9]","",test)
[1] "465123" "" "123"
所有這些與字符串一起跳舞的問題都是stringr包旨在解決的問題。
library(stringr)
str_extract_all('fasdjlk465fsdj123', '[0-9]')
[[1]]
[1] "4" "6" "5" "1" "2" "3"
# It is vectorized too
str_extract_all(rep('fasdjlk465fsdj123',3), '[0-9]')
[[1]]
[1] "4" "6" "5" "1" "2" "3"
[[2]]
[1] "4" "6" "5" "1" "2" "3"
[[3]]
[1] "4" "6" "5" "1" "2" "3"
stringr 背后的動機是在兩個原則下統一 R 中的字符串操作:
對函數( str_do_something
)使用合理且一致的命名方案。
使所有在其他編程語言中需要執行一步的所有字符串操作在 R 中執行 50 步,而在 R 中只執行一步。
grep
只會告訴您字符串是否匹配。
例如,如果您有:
values <- c("abcde", "12345", "abc123", "123abc")
然后
grep <- ("[0-9]", values)
[1] 2 3 4
這告訴您數組的元素 2,3 和 4 與正則表達式匹配。 您可以通過value=TRUE
返回字符串而不是索引。
如果要檢查匹配發生的位置,可以改用regexpr
> regexpr("[0-9]", values)
[1] -1 1 4 1
attr(,"match.length")
[1] -1 1 1 1
它告訴你第一場比賽在哪里發生。
更好的是,您可以使用gregexpr
進行多個匹配
> gregexpr("[0-9]", values)
[[1]]
[1] -1
attr(,"match.length")
[1] -1
[[2]]
[1] 1 2 3 4 5
attr(,"match.length")
[1] 1 1 1 1 1
[[3]]
[1] 4 5 6
attr(,"match.length")
[1] 1 1 1
[[4]]
[1] 1 2 3
attr(,"match.length")
[1] 1 1 1
不知道你從哪里得到的印象
> test <- "fasdjlk465öfsdj123"
> grep("[0-9]",test)
[1] 1
返回"fasdjlk465öfsdj123"
如果要返回匹配項,則需要將test
分解為它的組成部分,對這些部分進行grep
,然后使用從grep
返回的內容到 index test
。
> test <- strsplit("fasdjlk465öfsdj123", "")[[1]]
> matched <- grep("[0-9]", test)
> test[matched]
[1] "4" "6" "5" "1" "2" "3"
或者直接返回匹配的字符串,取決於你想要什么:
> grep("[0-9]", test, value = TRUE)
[1] "4" "6" "5" "1" "2" "3"
strapply
包中的 stripply 可以做這樣的提取:
> library(gsubfn)
> strapply(c("ab34de123", "55x65"), "\\d+", as.numeric, simplify = TRUE)
[,1] [,2]
[1,] 34 55
[2,] 123 65
它基於apply
范式,其中第一個參數是對象,第二個參數是修飾符( apply
邊距, strapply
正則表達式),第三個參數是應用於匹配的函數。
str_extract_all(obj, re)
在stringr包類似於strapply
專門在使用c
為函數,即,其將類似於strapply(obj, re, c)
strapply
支持 R 支持的正則表達式集,也支持 tcl 正則表達式。
請參閱http://gsubfn.googlecode.com 上的 gsubfn 主頁
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.