2017-01-24 3 views
2

ich den folgenden Code haben, die ich erwarte mir eine Liste von 3 zu geben, da es drei Elemente in texts:Vectorized stringr mit festen (wörtliche) Zeichen

library(stringr) 
texts <- c("I doubt it! :)", ";) disagree, but ok.", "No emoticons here!!!") 
smileys <- c(":)","(:",";)",":D") 
str_extract_all(texts, fixed(smileys)) 

Stattdessen bekomme ich ein Liste von vier (die Länge meines „Muster“ Parameter, hier die smileys Außerdem habe ich die folgende Warnmeldung erhalten.

Nachricht Warnung: In stri_extract_all_fixed (string, Muster, vereinfachen = vereinfachen: mehr Objekt Länge ist kein Vielfaches von kürzerem Objekt length```

Nun, ich kann mir nicht vorstellen Länge wird Spiel, wie ich für irgendwelche Zugriffe auf jede der Smileys in jedem Text suchen. Es ist nicht wie ich Saite 1 mit Muster übereinstimmen soll 1, String 2 mit Mustern 2 usw.

bewusst, dass ich stringi Verständnis von Vektorisierung bin vermasselt, ich habe diese stattdessen versucht:

texts %>% map(~ str_extract_all(.x, fixed(smileys))) 

Diese ist viel besser, da es mir eine Liste von 3 gibt, aber jedes Element ist wiederum eine Liste von vier.

Was ich versuche zu erreichen ist eine Liste von 3, die so wenig verschachtelt wie möglich ist. Jemand, irgendwo, hat das gelöst, aber ich kann nicht für das Leben von mir herausfinden oder googeln. Ich könnte eine for-Schleife darüber machen, aber ich betrachte mich als Bürger der sauberen ...

Dankbar für jede Hilfe.

+1

Nicht vertraut mit 'stringr' , aber ich glaube, dass Sie [grep unter Verwendung eines Zeichenvektors mit mehrfachen Mustern betrachten können] (http://stackoverflow.com/questions/7597559/grep-using-a-character-vector-of-patterns). Wenn Sie die Methode '' paste'' collapse = | '" verfolgen, dann müssen Sie vielleicht überlegen, wie ich mit Sonderzeichen wie \^$.? * | +() [{In meinem Regex?] (Http: // : //stackoverflow.com/questions/27721008/how-doi-i-deal-with-special-characters-like-in-my-regex) – Henrik

+0

Nicht sicher, ob das ist, was Sie suchen, aber Sie können es versuchen etwa so: 'pattern <- einfügen (" \\ Q ", Smileys," \\ E ", sep =" ", collapse =" | "); stringi :: stri_extract_all_regex (Texte, Muster) ' – Jota

+0

Ja, das Problem, einfach Dinge zusammen mit der Pipe einzufügen, ist, dass ich alle Klammern, Doppelpunkte usw., die viele Smileys ausmachen, entziffern muss! – Joy

Antwort

1

Sie können paste verwenden, um jedes Element von smiley mit \\Q und \\E und Zusammenbruch auf dem regulären Ausdruck „oder“ metacharacter (|) einzuwickeln ein einzelnes Muster zu bilden. Wie in der link Henrik shared erwähnt und dokumentiert auf ?regex und in der Handbuch werden Zeichen zwischen \\Q und \\E buchstäblich interpretiert.

pattern <- paste("\\Q", smileys, "\\E", sep = "", collapse = "|") 
# [1] "\\Q:)\\E|\\Q(:\\E|\\Q;)\\E|\\Q:D\\E" 

library(stringi) 
stri_extract_all_regex(texts, pattern) 
#[[1]] 
#[1] ":)" 
# 
#[[2]] 
#[1] ";)" 
# 
#[[3]] 
#[1] NA 

Base-R:

regmatches(texts, gregexpr(pattern, texts)) 
#[[1]] 
#[1] ":)" 
# 
#[[2]] 
#[1] ";)" 
# 
#[[3]] 
#character(0) 
     # If you want an NA, instead of a zero-length vector, 
     # then you could do something like: 
     # lapply(
     # regmatches(texts, gregexpr(pattern, texts)), 
     # function(ii) ifelse(is.character(ii) & length(ii) == 0L, NA, ii)) 

Und wenn Sie purrr verwenden wollen und vermeiden reguläre Ausdrücke, wäre eine Idee so etwas wie dieses:

library(purrr) 
library(stringr) 
texts %>% 
    map(~ unlist(str_extract_all(.x, fixed(smileys)))) 
#[[1]] 
#[1] ":)" 
# 
#[[2]] 
#[1] ";)" 
# 
#[[3]] 
#character(0) 
     # if you want NA, not a zero-length vector, you could add: 
     # %>% map(~ ifelse(is.character(.x) & length(.x) == 0L, NA, .x))