2012-10-17 22 views
10

Ho un bisogno di dividere sulle parole e segni finali (di punteggiatura di alcuni tipi). La pipa strana ("|") può essere considerata come un segno di fine. Ho il codice che le parole sui segni finali fino a quando non provo ad aggiungere il tubo. L'aggiunta del tubo rende il strsplit ogni carattere. Sfuggire a causa ed errore. Come posso includere il pipe nella sua espressione regolare?fuga pipe ("|") in una regex

x <- "I like the dog|." 

strsplit(x, "[[:space:]]|(?=[.!?*-])", perl=TRUE) 
#[[1]] 
#[1] "I" "like" "the" "dog|" "." 

strsplit(x, "[[:space:]]|(?=[.!?*-\|])", perl=TRUE) 
#Error: '\|' is an unrecognized escape in character string starting "[[:space:]]|(?=[.!?*-\|" 

Il risultato mi piacerebbe:

#[[1]] 
#[1] "I" "like" "the" "dog" "|" "." #pipe is an element 
+0

io sono sempre riluttanti a mettere i tag regex su questioni regex R perché si ottiene regexers da altre lingue e anche se le risposte sono simili che non si sovrappongano. –

risposta

16

Un modo per risolvere questo è quello di utilizzare la notazione \Q...\E per rimuovere il significato speciale di uno dei personaggi in .... Come si dice in ?regex:

Se si desidera rimuovere il significato speciale da una sequenza di caratteri , è possibile farlo mettendoli tra ‘\ Q’ e ‘\ E’. Questo è diverso da Perl in quell ‘$’ e ‘@’ sono trattati come letterali in ‘\ Q ... \ E’ sequenze in PCRE, mentre in Perl, ‘$’ e ‘@ perche’ interpolazione variabile.

Ad esempio:

> strsplit(x, "[[:space:]]|(?=[\\Q.!?*-|\\E])", perl=TRUE) 
[[1]] 
[1] "I" "like" "the" "dog" "|" "." 
+0

Interessante. Ho sicuramente bisogno di leggere su regex un po 'di più. +1 – A5C1D2H2I1M1N2O1R2T1

+0

@Joshua, mrdwab ha dato un'ottima risposta e questo è ancora più approfondito. Non ho mai nemmeno sentito parlare della cosa '\\ Q ... \\ E'. informazioni molto utili. –

+0

@TylerRinker: Neppure avevo mai sentito parlare, finché non ho letto la documentazione dopo aver visto la tua domanda. ;-) –

12

Il problema è in realtà il vostro segno meno, che dovrebbe entrare sia first or last:

strsplit(x, "[[:space:]]|(?=[|.!?*-])", perl=TRUE) 
strsplit(x, "[[:space:]]|(?=[.|!?*-])", perl=TRUE) 
strsplit(x, "[[:space:]]|(?=[.!|?*-])", perl=TRUE) 
strsplit(x, "[[:space:]]|(?=[-|.!?*])", perl=TRUE) 

e così via dovrebbero essere tutti dare l'output stai cercando.

Si può anche sfuggire il trattino, se si preferisce, ma ricordatevi di utilizzare due barre rovesciate!

strsplit(x, "[[:space:]]|(?=[.!?*\\-|])", perl=TRUE) 
+0

Entrambe le risposte eccellenti, josh ha dato ancora più dettagli. Grazie per la tua risposta +1 –