2013-03-22 13 views
8

Czekam na podział ciągu ogólnej formy, gdzie nawiasy kwadratowe oznaczają "sekcje" ciągu. Ex:split string with regex

x <- "[a] + [bc] + 1" 

i powrócić do postaci wektorowej, który wygląda tak:

"[a]" " + " "[bc]" " + 1" 

EDIT: Skończyło się przy użyciu to:

x <- "[a] + [bc] + 1" 
x <- gsub("\\[",",[",x) 
x <- gsub("\\]","],",x) 
strsplit(x,",") 

Odpowiedz

6

Widziałem kod TylerRinker i podejrzewam może być bardziej jasne niż to, ale to może służyć jako sposób na naukę inny zestaw funkcji. (Podobał mi się jego lepszy, zanim zauważyłem, że dzieli się on na spacje). Próbowałem dostosować to do pracy z strsplit, ale ta funkcja zawsze usuwa separatory. Może to można zaadaptować, aby uzyskać newstrsplit, który dzieli się na separatory, ale pozostawia je? Prawdopodobnie nie trzeba dzielić na pierwszej lub ostatniej pozycji i rozróżniać separatory otwierające i zamykające.

scan(text= # use scan to separate after insertion of commas 
      gsub("\\]", "],", # put commas in after "]"'s 
      gsub(".\\[", ",[", x)) , # add commas before "[" unless at first position 
     what="", sep=",") # tell scan this character argument and separators are "," 
#Read 4 items 
#[1] "[a]" " +" "[bc]" " + 1" 
+0

Podoba mi się to podejście, ponieważ nie jest zależne od białej przestrzeni do podziału. Utrzymanie białej przestrzeni na wyjściu nie było ważne dla tego zadania, więc zmodyfikowałem to tak, by działało z 'strplit': –

+0

Dziękuję za pozytywny komentarz, ale uważam, że @ juba jest lepszą odpowiedzią. Zamierzam go użyć do skonstruowania prostej funkcji parsowania, która akceptuje parę argumentów, aby zasygnalizować początku i koniec ograniczników, które zostaną zachowane. –

5

Jest to jeden leniwe podejście:

FUN <- function(x) { 
    all <- unlist(strsplit(x, "\\s+")) 
    last <- paste(c(" ", tail(all, 2)), collapse="") 
    c(head(all, -2), last) 
} 

x <- "[a] + [bc] + 1"  
FUN(x) 

## > FUN(x) 
## [1] "[a]" "+" "[bc]" " +1" 
+0

mówisz „leniwe”, ponieważ używasz spacji zamiast używać nawiasów oddzielić? –

+0

Tak (bez realnych intensywnych wyrażeń regularnych) –

5

Możesz obliczyć punkty podziału punktów y i korzystać substring:

split.pos <- gregexpr('\\[.*?]',x)[[1]] 
split.length <- attr(split.pos, "match.length") 
split.start <- sort(c(split.pos, split.pos+split.length)) 
split.end <- c(split.start[-1]-1, nchar(x)) 
substring(x,split.start,split.end) 
# [1] "[a]" " + " "[bc]" " + 1" 
+1

Idziemy. Wielki postęp w kierunku "gazety". Nie, żebym to zrozumiał w pełni, ale pomyślałem, że "gregexpr" będzie użyteczny. Byłem zaskoczony, że nie musisz używać "\\" "we wzorze. –

+0

Myślę, że ']' nie musi być zmieniona, ponieważ nie jest interpretowana jako koniec klasy znaków ze względu na fakt, że '[' jest. Hmm, nie jestem pewien, czy jestem czysty :-) – juba

+0

Miałem tę samą myśl, ale sugeruje, że "specjalność" jest bardziej zależna od kontekstu, niż bym się spodziewał. –

5

A oto wersja, która dzieli się na wspornikach i utrzymuje je w wyniku stosując dodatni uprzedzona i lookbehind:

splitme <- function(x) { 
    x <- unlist(strsplit(x, "(?=\\[)", perl=TRUE)) 
    x <- unlist(strsplit(x, "(?<=\\])", perl=TRUE)) 
    for (i in which(x=="[")) { 
    x[i+1] <- paste(x[i], x[i+1], sep="") 
    } 
    x[-which(x=="[")] 
} 
splitme(x) 
#[1] "[a]" " + " "[bc]" " + 1"