Regex per rimuovere gli zeri iniziali in R, a meno che il carattere finale (o unico) sia zero


9
gsub("(?<![0-9])0+", "", c("005", "0AB", "000", "0"), perl = TRUE)
#> [1] "5"  "AB" ""   ""
gsub("(^|[^0-9])0+", "\\1", c("005", "0AB", "000", "0"), perl = TRUE)
#> [1] "5"  "AB" ""   ""

L'espressione regolare sopra è da questo thread SO che spiega come rimuovere tutti gli zeri iniziali da una stringa in R. Come conseguenza di questa espressione regolare sia "000" che "0" vengono trasformati in "". Invece, desidero rimuovere tutti gli zeri iniziali da una stringa di caratteri, ad eccezione dei casi in cui il carattere finale risulta essere zero o l'unico carattere è zero.

"005" would become "5"
"0AB" would become "AB"
"000" would become "0"
"0"   would become "0"

Quest'altro thread SO spiega come fare ciò che voglio, ma non credo di ottenere la sintassi abbastanza corretta, applicando la soluzione in R. E non capisco davvero la distinzione tra la prima e la seconda soluzione di seguito ( se hanno davvero funzionato).

gsub("s/^0*(\d+)$/$1/;", "", c("005", "0AB", "000", "0"), perl = TRUE)  # 1st solution
# Error: '\d' is an unrecognized escape in character string starting ""s/^0*(\d"
gsub("s/0*(\d+)/$1/;", "", c("005", "0AB", "000", "0"), perl = TRUE)    # 2nd solution
# Error: '\d' is an unrecognized escape in character string starting ""s/0*(\d"

Qual è la regex corretta in R per ottenere ciò che voglio?

Risposte:


6

Puoi rimuovere tutti gli zeri dall'inizio di una stringa ma non l'ultimo:

sub("^0+(?!$)", "", x, perl=TRUE)

Guarda la demo di regex .

Dettagli

  • ^ - inizio di una stringa
  • 0+ - uno o più zeri
  • (?!$) - un lookahead negativo che non riesce la corrispondenza se c'è una fine della posizione della stringa immediatamente a destra della posizione corrente

Guarda la demo R :

x <- c("005", "0AB", "000", "0")
sub("^0+(?!$)", "", x, perl=TRUE)
## => [1] "5"  "AB" "0"  "0"

1
regexnovizio. Qual è la differenza di prestazione (o altre preferenze) tra il tuo modello e questo ^0*(.+)$o ^0+(.+)$?
M--

2
@ M-- Questi sono modelli diversi, si consiglia di confrontare solo le prestazioni di regexps equivalenti. I tuoi sono un po 'inefficienti come .possono corrispondere 0ed entrambi i modelli adiacenti sono quantificati indefinitamente, ma solo un pochino.
Wiktor Stribiżew il

4

Possiamo aggiungere un'altra condizione con una ricerca regex per verificare eventuali valori diversi da zero dopo uno o più zeri ( 0+)

sub("(?<![0-9])0+(?=[^0])", "", sub("^0+$", "0", v1), perl = TRUE)
#[1] "5"  "AB" "0"  "0" 

dati

v1 <- c("005", "0AB", "000", "0")

1
Non sono un regexguru in alcun modo, ma le soluzioni non sono efficienti, vero? Dato che ne hai due, subpotresti voler rimuovere tutti gli zeri iniziali e sostituirli ""con 0? sub("^$", "0", sub("^0+", "", v1), perl = TRUE)
M--

2
@ M-- Non sarebbe così efficiente, ma l'ho usato per seguire lo stesso codice dell'OP
akrun


3

È possibile utilizzare un'alternativa per abbinare tutti gli zeri nella stringa in un gruppo di acquisizione o abbinare tutti gli zeri dall'inizio della stringa.

Nella sostituzione utilizzare il gruppo 1.

^0*(0)$|^0+

Demo Regex | R demo

Per esempio

sub("^0*(0)$|^0+", "\\1", c("005", "0AB", "000", "0"))

Produzione

[1] "5"  "AB" "0"  "0"

O ancora meglio, come commentato da Wiktor Stribiżew , potresti usare catturare un singolo 0 in un gruppo e ripetere il gruppo stesso per catturare l'ultima istanza di uno zero.

^(0)+$|^0+

Demo Regex


3
Userei^(0)+$|^0+
Wiktor Stribiżew

3
Sembra che sub("^0+(?!$)", "", x, perl=TRUE)funzionerà anche
Wiktor Stribiżew il

2

Un'altra regexopzione:

^0*(.+)$

Ecco una demo regex .

Usando base::subin R:

sub("^0*(.+)$", "\\1", c("005", "0AB", "000", "0"))  

 ## [1] "5"  "AB" "0"  "0" 

Ecco un R demo .

O espandendo la risposta di @ akrun :

sub("^$", "0", sub("^0+", "", c("005", "0AB", "000", "0")), perl = TRUE)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.