2012-06-13 8 views
15

Funkcja strsplit w R ma, dopasuj i usuń dane wyrażenie regularne, aby podzielić resztę łańcucha na wektory.Jak powinienem podzielić i zachować elementy za pomocą strsplit?

>strsplit("abc123def", "[0-9]+") 
[[1]] 
[1] "abc" "" "" "def" 

Ale w jaki sposób powinienem podzielić strunę w ten sam sposób, używając wyrażenia regularnego, ale także zachować dopasowania? Potrzebuję czegoś takiego.

>FUNCTION("abc123def", "[0-9]+") 
[[1]] 
[1] "abc" "123" "def" 

Korzystanie strapply („abc123def”, „[0-9] + | [az] +”) pracuje tutaj, ale co jeśli reszta ciąg innych niż mecze nie mogą zostać przechwycone przez wyrażenie regularne ?

+0

Możesz przechwytywać wszystkie znaki za pomocą wzoru "[0-9] + | [^ 0-9] +" lub wydłużyć wzór, aby uchwycić wszystko inne i odrzucić je za pomocą funkcji FUN = (x), jeśli (grepl ("^ [0-9a-z] + $", x)) x –

+0

Cześć, widzę, że jesteś nowy w SO. Jeśli uważasz, że odpowiedź rozwiązała problem, zaznacz go jako "zaakceptowany", klikając zielony znacznik wyboru. Pomaga to skupić się na starszych SO, które wciąż nie mają odpowiedzi. http://meta.stackexchange.com/questions/88535/asking-for-someone-to-accept-your-answer/135824#135824 –

Odpowiedz

22

Zasadniczo wydaje mi się, że nie należy dzielić się na [0-9]+, ale podzielić na przejście między [0-9]+ i wszystkim innym. W twoim ciągu to przejście nie istnieje wcześniej. Aby wstawić go, można wstępnie proces gsub i back-odniesienie:

test <- "abc123def" 
strsplit(gsub("([0-9]+)","~\\1~",test), "~") 

[[1]] 
[1] "abc" "123" "def" 
+0

Nigdy nie wiedziałem o regexie odwołującym się wstecz. Tego właśnie chciałem i dziękuję bardzo. – jackson

+0

Cieszę się, że rozwiązany odpowiedni problem :-) –

+1

Naprawdę sprytna sztuczka! – voidHead

2

Można użyć strapply z pakietu gsubfn.

test <- "abc123def" 
strapply(X=test, 
     pattern="([^[:digit:]]*)(\\d+)(.+)", 
     FUN=c, 
     simplify=FALSE) 

[[1]] 
[1] "abc" "123" "def" 
5

Można używać twierdzeń dotyczących spojrzeń.

> test <- "abc123def" 
> strsplit(test, "(?<=\\D)(?=\\d)|(?<=\\d)(?=\\D)", perl=T) 
[[1]] 
[1] "abc" "123" "def" 
+6

Dlaczego upadły? Działa idealnie dla tego wejścia. –

+1

+1: To nie tylko działa, ale i to rozwiązanie jest o wiele bardziej eleganckie! Rozważ przypadek, w którym chcesz podzielić formuły za każdym razem, gdy napotkasz operatora plus lub minus. Pomiędzy nimi masz nazwy zmiennych, które chciałbyś edytować. Dlatego możesz go podzielić, pozostać operatorami jako oddzielnymi ciągami, edytować nazwy zmiennych, a następnie ponownie połączyć cały zestaw łańcuchów. Działa idealnie z tym rozwiązaniem bez utraty operatorów plus i minus! – ToJo

Powiązane problemy