grep

2011-08-04 28 views
17
Ben "001" veya "100" veya "000" 0 ve 1 4 karakterden oluşan bir dizede oluşursa, görmek istiyorum

kullanarak farklı olanakları ile bir dize eşleştirmek. Örneğin, bir 4 karakter dizesi "1100" veya "0010" veya "1001" veya "1111" gibi olabiliriz. Bir dizede birçok dizeyi tek bir komutla nasıl eşleştirebilirim? grep

Ben grep model eşleştirmesi için kullanılabilir, ancak grep kullanarak, bir seferde sadece bir dize kontrol edebilirsiniz biliyorum. Birden fazla dizenin başka bir komutla veya grep ile birlikte kullanılıp kullanılamayacağını bilmek istiyorum.

cevap

37

Evet, yapabilirsiniz. Bir grep desende |or aynı anlama sahiptir. Böylece deseniniz için "001|100|000" kullanarak deseninizi test edebilirsiniz. Aynı zamanda, grep vektörleştirilmiş, dolayısıyla tüm bu tek adımda yapılabilir: (. Bu durumda ilk üç yılında) Bu eşleştirme kalıbını içerdiği için vektörlerin hangi bir dizin döndürür

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

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

Bazen eşleşti sizin vektör öğelerin hangi söyler mantıksal vektör olması daha uygundur. Sonra grepl kullanabilirsiniz:

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

R. düzenli ifadeler hakkında yardım için ?regex bakın


Düzenleme: deseni oluşturarak önlemek için elle biz paste kullanabilirsiniz:

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

@andrie, bu kesinlikle parlak, sadece basit bir regex iken,

+4

@DavidArenburg :-) yıllarca imkansız olduğunu varsayarak, acı deneyimlerinden öğrendim. Hiçbir şey mümkün değildir. Nasıl! – Andrie

2

ek modeller eklemek için -e argüman kullanın:

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

Üzgünüm Ama bu yine de yararlıdır R. – Narayani

+0

bunu yapmak istediğini söylemeyi unutmuşum. – marbel

6

İştekullanarak tek çözümdür 0 paket

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

Ayrıca data.table kütüphanesinden %like% operatörünü kullanabilirsiniz.

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%' ifadesinin 'grepl' için sadece bir sarmalayıcı olduğunu,'?%% Like% '' Arguments: ... \t pattern \t grepl’e aktarıldığını unutmayın. En az "data.table" sürümüne kadar 1.10.4-2. –

1

o zaman stringi paketinden stri_detect fonksiyonunu kontrol etmelidir mantıksal vektör istiyorum. Bu bir ilave cevabı yapmak için

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

Üzgünüz, ama bir yorum için çok fazla satır:

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

Ve bazı kriterler: Senin durumunda desen yüzden bu bir kullanmak, düzenli ifade olduğunu.

Tek eşleştirme deseni olarak kullanılmak üzere paste(..., collapse = "|") aracılığıyla yapıştırılabilecek öğelerin sayısının sınırlı olduğunu hatırlatmak istedim - aşağıya bakın. Belki biri tam olarak sınırın nerede olduğunu söyleyebilir mi? Kuşkusuz sayı gerçekçi olmayabilir, ama göreve bağlı tamamen bizim hususlar dışında edilmemelidir gerçekleştirilecek.

Çok fazla sayıda öğe için, desenin her bir öğesinin kontrol edilmesi için bir döngü gerekir.

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)