2017-04-26 2 views
0

Ich versuche, eine Spalte mit mehreren Schlüssel: Wert-Paare aus einer Tabelle mit tidyr :: extract() zu extrahieren. Ich habe meinen regulären Ausdruck mit stringr :: str_view() verfeinert, aber ich bekomme ein unerwartetes Verhalten - tidyr :: extract() scheint mit einer anderen Zeichenfolge als stringr :: str_view() übereinzustimmen.stringr :: str_view() und tidyr :: extract() Unterschiede im regulären Ausdruck?

Wie kann ich meine Verwendung von tidyr :: extract() ändern, um das gewünschte Verhalten zu erhalten?

Beispiel:

library(tidyverse) 
library(stringr) 

df <- as_data_frame('protein_id "ENSP00000260585.7"; tag "basic"; tag "appris_principal"; tag "CCDS"; tag "seleno"; ccdsid "CCDS46240.1"; havana_gene "OTTHUMG00000151931.3"; havana_transcript "OTTHUMT00000324484.3";') 

# match I expect: 'tag "basic"; tag "appris_principal"; tag "CCDS"; tag "seleno"; ' 
str_view(df$value, '(tag "(?:.+?)"; +)+') 

# match I get: 'tag \"seleno\"; ' 
(df %>% extract(value, "tags", '(tag "(?:.+?)"; +)+', remove = FALSE))$tags 

Ich möchte den Satz von 4 Tag Schlüssel extrahieren: Werte in eine neue Spalte Tags genannt, die ich werde dann etwas mehr ordentlich. Aber das ist schwer, wenn ich nur eines der 4 Paare aus dem Extrakt bekomme!

Ich denke, dass meine obigen Kommentare klar sind, aber nur für den Fall, dass mein Ausdruck übersetzt, um meine Absicht zu beschreiben, würde ich es so umschreiben: Ich würde gerne 0 oder mehr Wiederholungen von 'Tag' (0 oder mehr Zeichen, faule Bewertung) "; (optionaler Platz)" (gierige Bewertung).

Antwort

0

Ah - es hat mit der gierigen vs. faulen Takes zu tun, und die Tatsache, dass extract() "jede [capture] Gruppe in eine neue Spalte verwandelt". Also brauche ich nur eine einzige Capture-Gruppe:

> (df %>% extract(value, "tags", '((?:tag "(?:.+?)"; +)+)', remove = FALSE))$tags 

[1] "tag \"basic\"; tag \"appris_principal\"; tag \"CCDS\"; tag \"seleno\"; " 

reguläre Ausdrücke ...