2014-11-30 22 views
6

Sto tentando di rimuovere tutte le cifre in una stringa tranne il primo gruppo di cifre. Quindi, in altre parole, tutti gli insiemi di cifre che si ripetono, ci potrebbero essere 1 set o 10+ set nella stringa, ma voglio solo mantenere il primo set insieme al resto della stringa.R rimuovere sequenze di cifre ripetute

Ad esempio, la seguente stringa:

x <- 'foo123bar123baz123456abc1111def123456789' 

Il risultato sarebbe:

foo123barbazabcdef 

sto provato utilizzando gsub e sostituendo \d+ con una stringa vuota ma questa sostituisce tutte le cifre nel stringa, ho anche provato a usare i gruppi per catturare alcuni dei risultati ma non ho avuto fortuna.

risposta

3

È possibile eseguire questa operazione tramite il verbo PCRE (*SKIP)(*F).

^\D*\d+(*SKIP)(*F)|\d+ 

^\D*\d+ corrisponde a tutti i caratteri dall'inizio fino al primo numero. (*SKIP)(*F) causa il fallimento della corrispondenza e quindi il motore regex tenta di far corrispondere i caratteri utilizzando il modello che era sul lato destro di | ovvero \d+ rispetto alla stringa rimanente. Poiché (*SKIP)(*F) è un verbo PCRE, è necessario abilitare il parametro perl=TRUE.

DEMO

Codice:

> x <- 'foo123bar123baz123456abc1111def123456789' 
> gsub("^\\D*\\d+(*SKIP)(*F)|\\d+", "", x, perl=TRUE) 
[1] "foo123barbazabcdef" 
7

Usando gsub è possibile utilizzare la funzione di \G, un'ancora che può corrispondere ad una delle due posizioni.

x <- 'foo123bar123baz123456abc1111def123456789' 
gsub('(?:\\d+|\\G(?<!^)\\D*)\\K\\d*', '', x, perl=T) 
# [1] "foo123barbazabcdef" 

Spiegazione:

(?:   # group, but do not capture: 
    \d+   # digits (0-9) (1 or more times) 
|   # OR 
    \G(?<!^) # contiguous to a precedent match, not at the start of the string 
    \D*   # non-digits (all but 0-9) (0 or more times) 
)\K   # end of grouping and reset the match from the result 
\d*   # digits (0-9) (0 or more times) 

In alternativa, è possibile utilizzare un gruppo opzionale:

gsub('(?:^\\D*\\d+)?\\K\\d*', '', x, perl=T) 

Un altro modo che trovo utile e non richiede (*SKIP)(*F) verbi backtracking o \G e la funzione \K consiste nell'utilizzare l'operatore alternation nel contesto ponendo ciò che si desidera far corrispondere a un gruppo di cattura sul lato sinistro e inserire ciò che si desidera escludere sul lato destro, (dicendo tiro questa via, è spazzatura ...)

gsub('^(\\D*\\d+)|\\d+', '\\1', x) 
+1

Gli scioperi maestri di nuovo –

+0

Non prendertela, ma il tuo secondo modo non funziona se la stringa dell'oggetto inizia con le cifre http://regex101.com/r/yW4aZ3/140, perché il lato destro può inghiottire il lato sinistro in cui devi invertire il loro ordine '^(\ D * \ d +) | \ d + 'e sostituisci con' \ 1' http://regex101.com/r/yW4aZ3/141 - una variante dalla soluzione di Avinash, o '^ \ D * \ d + \ K | \ d + ' –

+0

@alphabravo era un errore di battitura, ho corretto la seconda opzione. – hwnd

Problemi correlati