2012-11-28 13 views
7

Ho la seguente espressione regolare che mi piacerebbe prendere tutto dall'inizio della frase fino al primo ##. Potrei usare strsplit come dimostrano di fare questa operazione, ma preferisco una soluzione gsub. Se lo gusub non è lo strumento corretto (penso che sia comunque) preferirei una soluzione di base perché voglio imparare gli strumenti regex di base.Grab dall'inizio alla prima occorrenza di carattere con gsub

x <- "gfd gdr tsvfvetrv erv tevgergre ## vev fe ## vgrrgf" 

strsplit(x, "##")[[c(1, 1)]] #works 

gsub("(.*)(##.*)", "\\1", x) #I want to work 

risposta

13

basta aggiungere un carattere, mettendo un ? dopo il primo quantificatore per renderlo "non-greedy":

gsub("(.*?)(##.*)", "\\1", x) 
# [1] "gfd gdr tsvfvetrv erv tevgergre " 

Ecco la relativa documentazione, da ?regex

Con la ripetizione di default è avido, quindi viene utilizzato il numero massimo possibile di ripetizioni. Questo può essere modificato in "minimo" aggiungendo "?" al quantificatore.

+0

Grazie per una soluzione 'gsub' e spiegando cosa c'era di sbagliato nel mio modo di pensare. +1 –

1

Prova questa come regex

^[^#]+ 

comincia all'inizio della stringa e corrisponde a qualsiasi cosa non un # fino al primo #

4

direi:

sub("##.*", "", x) 

Rimuove tutto compreso e dopo la prima occorrenza di ##.

+0

Funziona alla grande e prima soluzione. Grazie. +1 –

3

In questo caso, direi che per l'inverso, vale a dire sostituire tutto a seguito # con una stringa vuota:

gsub("#.*$", "", x) 
[1] "gfd gdr tsvfvetrv erv tevgergre " 

ma è anche possibile utilizzare il modificatore non avido ? per rendere il vostro lavoro in regex il modo in cui ha suggerito:

gsub("(.*?)#.*$", "\\1", x) 
[1] "gfd gdr tsvfvetrv erv tevgergre " 
+0

Grazie. Questa è stata la prima soluzione 'gsub' che ho chiesto. +1 –

1

Non ci sono più risposte più semplici già qui, ma dal momento che avete indicato nel vostro domanda che desideri conoscere il supporto regex nella base di R, Ecco un altro modo, utilizzando positivo lookahead (?=#) e non avido opzione (?U) .

regmatches(x, regexpr('(?U)^.+(?=#)', x, perl=TRUE)) 
[1] "gfd gdr tsvfvetrv erv tevgergre " 
+0

grazie per aver dedicato del tempo ad aggiungere ulteriore regex. Ho usato 'regmatches 'solo alcune volte ma questo è stato con una grande quantità di assistenza. Grazie.+1 –

1

Ecco un altro approccio che utilizza più strumenti di stringa invece di un'espressione regolare più complicata. Si trova la prima posizione della prima ## e poi estrae la sottostringa fino a quel momento:

library(stringr) 
x <- "gfd gdr tsvfvetrv erv tevgergre ## vev fe ## vgrrgf" 
loc <- str_locate(x, "##") 
str_sub(x, 1, loc[, "start"] - 1) 

In generale, credo che questo tipo di approccio step-by-step è più gestibile di espressioni regolari complesse.

+0

Ho notato che hai consigliato l'approccio passo alla regexing anche in un post precedente. Questo approccio (in particolare con piccole quantità di testo) è spesso più gestibile. +1 –

Problemi correlati