2014-10-03 12 views
6

Cercavo di comprimere tutti multiple (2 o più) caratteri di spaziatura all'interno di elementi di un vettore in una singola, utilizzando gsub(), ad esempio:R regex: problemi con vettori caratteri contenenti AN

x1 <- c(" abc", "a b c ", "a b c") 
gsub("\\s{2,}", " ", x1) 
[1] " abc" "a b c " "a b c" 

Ma non appena il vettore contiene NA la sostituzione fallisce:

x2 <- c(NA, " abc", "a b c ", "a b c") 
gsub("\\s{2,}", " ", x2) 
[1] NA " " " " " " 

Tuttavia, funziona bene se si usa Perl-come le espressioni regolari:

gsub("\\s{2,}", " ", x2, perl = TRUE) 
[1] NA  " abc" "a b c " "a b c" 

Qualcuno ha suggerimenti sul perché le proprie espressioni regolari di R si comportano in questo modo? Sto usando R 3.1.1 su Linux x86-64 se questo aiuta.

+0

Hai controllato l'aggiunta più indietro barre? In R è piuttosto difficile. Di solito hai bisogno di tre per riconoscere questo tipo di espressioni – Llopis

+0

@Llopis Che non è corretto. La regex è in realtà '\ s', a cui anteponiamo un singolo backslash per arrivare a \\\ s'. – jbaums

+0

Confermato anche su OS X. Sia '\ s' che' [[: space:]] 'mostrano il comportamento, mentre un carattere di spazio letterale (o classe di caratteri space/tab) funziona bene. Sto pensando bug in R. –

risposta

2

Non ho rilevato il codice sorgente ma funziona anche se si utilizza il parametro useBytes=TRUE (senza il parametro perl=TRUE). Dall'aiuto: "se useBytes è TRUE l'abbinamento viene eseguito byte per byte anziché carattere per carattere." Questo potrebbe essere parte del motivo per cui non funziona in gsub.

Tuttavia, regexpr, regexec e gregexpr ogni trovare tutte le posizioni corrette (ho sostituito \\s con [[:space:]]: per migliorare la leggibilità e utilizzato solo in uscita dal regexpr:.

regexpr("[[:space:]]{2,}", x2) 

## [1] NA 1 1 1 
## attr(,"match.length") 
## [1] NA 5 9 6 

Così, l'espressione regolare di per sé soddisfacente

Aggiornamento

: una rapida occhiata a do_gsub in R 3.1.1's grep.c non ha dato molto intuizione (è un labirinto contorto di if/else dichiarazioni :-), ma vorrei quasi cal Questo è un bug.

+2

Cosa? un bug in Regex? Come potrebbe qualcuno dirlo? :-) –