2015-11-22 31 views
6

Bu yaygın bir sorundur ve bazı SO'lar da dahil olmak üzere pek çok web sayfası buldum, ancak nasıl uygulanacağını anlayamadım.REGEX in R: bir dizgeden bir sözcük ayıklamak

REGEX için yeni ve bir cümleyle ilk birkaç kelimeyi ayıklamak için R'de kullanmak istiyorum.

örneğin benim cümle (i ilk dört kelime gerekiyorsa) i son dört gerekirse

z = "I love stack overflow it is such a cool site" 

id (varlık olarak benim çıkış olması

[1] "I love stack overflow" 

veya ister ise kelime) elbette

[1] "such a cool site" 

aşağıdaki işleri

paste(strsplit(z," ")[[1]][1:4],collapse=" ") 
paste(strsplit(z," ")[[1]][7:10],collapse=" ") 

ama çok büyük dosyaları ile uğraşmak gerekir olarak i performans sorunları için regex çözüm denemek istiyorum (ve ayrıca bu konuda bilmeden uğruna) Ben dahil olmak üzere birçok bağlantılar baktı

Regex to extract first 3 words from a string ve http://osherove.com/blog/2005/1/7/using-regex-to-return-the-first-n-words-in-a-string.html

yüzden ben başka şeyler denedik ama genellikle beni ya bütün dize döndürdü

gsub("^((?:\S+\s+){2}\S+).*",z,perl=TRUE) 
Error: '\S' is an unrecognized escape in character string starting ""^((?:\S" 

gibi şeyler denedik veya boş dize. Substr ile ilgili başka bir sorun, bir liste döndürmesidir. [[]] operatörünün büyük dosyalar ile uğraşırken bazı şeyleri yavaşladığını ve bazı şeyleri uyguladığını görebilirsiniz.

R'de kullanılan sözdizimi biraz farklı görünüyor mu? teşekkürler!

+2

R regex'te çift çıkışları kullanmanız gerekir. '\ S' ->' \\ S' –

+0

Ayrıca, stringi :: stri_extract_all_words (z) [[1]] [1: 4] 'i de kullanabilirsiniz ve kullanımı daha kolaydır ve normal ifadeleri bilmesi gerekmez. Yine de kelimeleri ayrı bir değer elde edeceksiniz. –

+0

Sadece [önceki sorunuzda] paylaştığım aynı fikri kullanamazdınız (http://stackoverflow.com/questions/33785594/manipulate-char-vectors-inside-a-data-table-object-in -r)? Sadece @stribizhev tarafından işaret edildiği gibi, R'deki ters eğik çizgileri iki katına çıkarmanız gerekir. – A5C1D2H2I1M1N2O1R2T1

cevap

5

Zaten bir cevap kabul ettik, ancak aslında üzerinde cevabını almaya çok yakın beri, sen R regex hakkında biraz daha anlamasına yardımcı bir araç olarak bu paylaşmak için gidiyorum senin kendi.

  1. Sen tek ters eğik çizgi (\) kullanılır:


    sizin gsub yaklaşımla iki sorun vardır. R, özel karakterler olduklarından bunlardan kaçmanızı gerektirir. Başka bir ters eğik çizgi ekleyerek onları kaçarsınız (\\). nchar("\\") yaparsanız, "1" döndürdüğünü görürsünüz.

  2. Değiştirme işleminin ne olacağını belirtmediniz. Burada hiçbir şeyi değiştirmek istemiyoruz, ancak dizenin belirli bir bölümünü yakalamak istiyoruz.Grupları (...) parantez içinde yakalarsınız ve daha sonra grubun sayısına göre bunlara başvurabilirsiniz. Burada sadece bir grup var, bu yüzden "\\1" olarak anıyoruz. "Z" içeriğinin baştan

    • Work:

      sub("^((?:\\S+\\s+){2}\\S+).*", "\\1", z, perl = TRUE) 
      # [1] "I love stack" 
      

      Bu aslında söylediğini:

Sen gibi bir şey denedim.

  • Başlangıç ​​oluşturarak grup 1.
  • (\S+\s+) iki kez {2} Arkasında boşluk (bir kelime gibi) olmayan boşluk ve non-beyaz alanlara daha sonra sonraki seti (\S+) bulun. Bu, üçüncü kelimeden sonra da boşluğu elde etmeden 3 kelime alacaktır. Bu nedenle, farklı bir kelime sayısı istiyorsanız, {2}'u, gerçekte takip ettiğiniz numaradan daha az olacak şekilde değiştirin.
  • Burada 1. grubu sonlandırın.
  • Daha sonra, grup 1'in içeriğini (\1) "z" den döndürün.

  • sadece yakalama grubunun konumunu değiştirmek ve maç için desen sonunda koymak, son üç kelime almak için.

    sub("^.*\\s+((?:\\S+\\s+){2}\\S+)$", "\\1", z, perl = TRUE) 
    # [1] "a cool site" 
    
    +0

    teşekkürler. @Ananda Mahto. Son 4 kelimeden oluşan bir ifadeyi "alt" işlevini kullanarak verir misiniz? –

    +1

    @FaguiCurtain, Referansı, satırın başına sonuna kadar sabitlenmekten çok değiştirdim, örneğin: ^. * ((?? \\ S + \\ s +) {2} \\ S +) $ '. 3 yerine 4 kelime almak için "2" yi "3" olarak değiştirin. – A5C1D2H2I1M1N2O1R2T1

    3

    İlk dört kelimeyi almak için.

    library(stringr) 
    str_extract(x, "^\\s*(?:\\S+\\s+){3}\\S+") 
    

    Son dördünü almak için.

    str_extract(x, "(?:\\S+\\s+){3}\\S+(?=\\s*$)") 
    
    +0

    veya 'alt ("^\\ s * ((?: \\ S + \\ s +) {3} \\ S +) * "," \\ 1 ", x)' –

    +0

    'sub' işlevini kullanarak bana doğru regex'i verebilir misiniz. 10.000'lik bir örnek üzerinde bir test yaptım ve R tabanından gelen 'alt' fonksiyonu 'kütüphaneden (stringr)' gelen str_extract'dan 30 kat daha hızlıdır. teşekkürler –

    +0

    Ben aptalım ama işlevi nasıl ayarlayacağımı bilmiyorum. alt ("(?: \\ S + \\ s +) {3} \\ S + (? = \\ s * $)", yedek = "", z, perl = TRUE) "geri geliyor" "Ben seviyorum yığının taşması "her şeydir ama son 4 kelimesi BUT ... –

    İlgili konular