그렙

2011-08-04 4 views
17
내가 "001" 또는 "100" 또는 "000"01 4 개 문자열에 발생하는 경우,보고 싶은

를 사용하는 다른 가능성을 가진 문자열을 일치. 예를 들어, 4 자 문자열은 "1100" 또는 "0010" 또는 "1001" 또는 "1111"과 같을 수 있습니다. 한 문자열의 많은 문자열을 단일 명령과 어떻게 대응시킬 수 있습니까?그렙

grep은 패턴 일치에 사용할 수 있지만 grep을 사용하면 한 번에 하나의 문자열 만 검사 할 수 있습니다. 여러 문자열을 다른 명령 또는 grep 자체와 함께 사용할 수 있는지 알고 싶습니다.

답변

37

예, 할 수 있습니다. grep 패턴의 |or과 같은 의미입니다. 따라서 패턴으로 "001|100|000"을 사용하여 패턴을 테스트 할 수 있습니다. 동시에, grep은 벡터화, 그래서이 모든 것이 한 번에 수행 할 수 있습니다. (이 경우 처음 세에서)이 일치하는 패턴을 포함하여 벡터의 어느 인덱스를 반환

x <- c("1100", "0010", "1001", "1111") 
pattern <- "001|100|000" 

grep(pattern, x) 
[1] 1 2 3 

때로는 벡터의 어떤 요소가 일치했는지 알려주는 논리 벡터를 갖는 것이 더 편리합니다. 그런 다음 grepl를 사용할 수 있습니다

grepl(pattern, x) 
[1] TRUE TRUE TRUE FALSE 

는 R.에서 정규 표현식에 대한 도움을 ?regex를 참조


편집 : 패턴을 생성을 방지하기 위해 수동으로 우리는 paste를 사용할 수 있습니다

myValues <- c("001", "100", "000") 
pattern <- paste(myValues, collapse = "|") 
+0

@andrie,이 절대적으로 찬란한 것은 몇 년 동안 불가능하다고 가정하고있었습니다. 단순한 정규식 인 반면

+4

@DavidArenburg :-) 나는 R에서 불가능한 것이 없다는 것을 쓴 경험에서 배웠습니다. 방법! – Andrie

2

추가 패턴을 추가 할 -e 인수를 사용

echo '1100' | grep -e '001' -e '110' -e '101' 
+2

미안하지만, R에서 이것을하고 싶다는 걸 잊었습니다. – Narayani

+0

어쨌든 유용합니다. – marbel

6

을 사용하는 한 가지 해결책이 있습니다. 0 패키지

require(stringr) 
mylist = c("1100", "0010", "1001", "1111") 
str_locate(mylist, "000|001|100") 
1

는 또한 data.table 라이브러리에서 %like% 연산자를 사용할 수 있습니다.

library(data.table) 

# input 
    x <- c("1100", "0010", "1001", "1111") 
    pattern <- "001|100|000" 

# check for pattern 
    x %like% pattern 

> [1] TRUE TRUE TRUE FALSE 
+0

'% like %'는'grepl'에 대한 래퍼 일 뿐이므로'? % like %' "를 확인하십시오 : 인수 : ... \t 패턴 \t grepl로 넘어갔습니다." 최소한'data.table' 버전 1.10.4-2까지. –

1

당신은 다음 stringi 패키지에서 stri_detect 기능을 확인해야 논리적 벡터를합니다. 이위한 추가적인 대답을 만들기위한

require(microbenchmark) 
test <- stri_paste(stri_rand_strings(100000, 4, "[0-1]")) 
head(test) 
## [1] "0001" "1111" "1101" "1101" "1110" "0110" 
microbenchmark(stri_detect_regex(test, pattern), grepl(pattern, test)) 
Unit: milliseconds 
          expr  min  lq  mean median  uq  max neval 
stri_detect_regex(test, pattern) 29.67405 30.30656 31.61175 30.93748 33.14948 35.90658 100 
      grepl(pattern, test) 36.72723 37.71329 40.08595 40.01104 41.57586 48.63421 100 
0

죄송하지만 댓글에 대한 너무 많은 라인입니다 :

stri_detect_regex(x, pattern) 
## [1] TRUE TRUE TRUE FALSE 

그리고 몇 가지 벤치 마크 : 귀하의 경우 패턴은 그래서이 하나를 사용 정규식입니다.

단일 일치 패턴으로 사용하기 위해 paste(..., collapse = "|")을 통해 붙여 넣을 수있는 항목의 수가 제한되어 있습니다. 아래를 참조하십시오. 어쩌면 누군가가 한계가 정확히 어디에 있는지 말할 수 있을까요? 틀림없이 숫자는 현실적이지 않을 수도 있지만 수행 할 작업에 따라 우리의 고려 사항에서 완전히 제외되어서는 안됩니다.

정말 많은 수의 항목의 경우 패턴의 각 항목을 확인하는 데 루프가 필요할 수 있습니다.

set.seed(0) 
samplefun <- function(n, x, collapse){ 
    paste(sample(x, n, replace=TRUE), collapse=collapse) 
} 

words <- sapply(rpois(10000000, 8) + 1, samplefun, letters, '') 
text <- sapply(rpois(1000, 5) + 1, samplefun, words, ' ') 

#since execution takes a while, I have commented out the following lines 

#result <- grepl(paste(words, collapse = "|"), text) 

# Error in grepl(pattern, text) : 
# invalid regular expression 
# 'wljtpgjqtnw|twiv|jphmer|mcemahvlsjxr|grehqfgldkgfu| 
# ... 

#result <- stringi::stri_detect_regex(text, paste(words, collapse = "|")) 

# Error in stringi::stri_detect_regex(text, paste(words, collapse = "|")) : 
# Pattern exceeds limits on size or complexity. (U_REGEX_PATTERN_TOO_BIG) 
관련 문제