Regex pour supprimer les zéros de tête dans R, à moins que le caractère final (ou unique) soit zéro

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'expression régulière ci - dessus provient de ce thread SO expliquant comment supprimer tous les zéros de tête d'une chaîne dans R. En conséquence de cette expression régulière, "000" et "0" sont transformés en "". Au lieu de cela, je veux supprimer tous les zéros de tête d'une chaîne de caractères, sauf dans les cas où le caractère final se trouve être zéro ou le seul caractère est zéro.

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

Cet autre thread SO explique comment faire ce que je veux, mais je ne pense pas que je reçois la syntaxe tout à fait correcte, en appliquant la solution dans R. Et je ne comprends pas vraiment la distinction entre la 1ère et la 2ème solution ci-dessous ( s'ils fonctionnaient bien).

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"

Quelle est l'expression rationnelle appropriée dans R pour obtenir ce que je veux?

Jason Hunter
la source

Réponses:

6

Vous pouvez supprimer tous les zéros du début d'une chaîne mais pas le dernier:

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

Voir la démo regex .

Détails

  • ^ - début d'une chaîne
  • 0+ - un ou plusieurs zéros
  • (?!$) - un lookahead négatif qui échoue la correspondance s'il y a une position de fin de chaîne immédiatement à droite de l'emplacement actuel

Voir la démo R :

x <- c("005", "0AB", "000", "0")
sub("^0+(?!$)", "", x, perl=TRUE)
## => [1] "5"  "AB" "0"  "0"
Wiktor Stribiżew
la source
1
regexNoob. Quelle est la différence de performances (ou d'autres préférences) entre votre modèle et celui-ci ^0*(.+)$ou ^0+(.+)$?
M--
2
@ M-- Ce sont des modèles différents, il est recommandé de comparer uniquement les performances des expressions rationnelles équivalentes. Les vôtres sont un peu inefficaces car .peuvent correspondre 0et les deux modèles adjacents sont quantifiés indéfiniment, mais juste un tout petit peu.
Wiktor Stribiżew
4

Nous pouvons ajouter une condition supplémentaire avec une recherche d'expression régulière pour vérifier les valeurs non nulles après un ou plusieurs zéros ( 0+)

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

Les données

v1 <- c("005", "0AB", "000", "0")
akrun
la source
1
Je ne suis regexen aucun cas un gourou mais les contournements ne sont pas efficaces, n'est-ce pas? Puisque vous en avez deux, subvous pouvez supprimer tous les zéros de tête et les remplacer ""par 0? sub("^$", "0", sub("^0+", "", v1), perl = TRUE)
M--
2
@ M-- Ce ne serait pas aussi efficace, mais je l'ai utilisé pour suivre le même code que l'OP
akrun
3

Vous pouvez utiliser une alternance pour faire correspondre tous les zéros de la chaîne dans un groupe de capture ou faire correspondre tous les zéros depuis le début de la chaîne.

Dans le groupe d'utilisation de remplacement 1.

^0*(0)$|^0+

Démo Regex | Démo R

Par exemple

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

Production

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

Ou encore mieux, comme l'a commenté Wiktor Stribiżew , vous pouvez utiliser la capture d'un seul 0 dans un groupe et répéter le groupe lui-même pour capturer la dernière instance d'un zéro.

^(0)+$|^0+

Démo Regex

Le quatrième oiseau
la source
3
J'utiliserais^(0)+$|^0+
Wiktor Stribiżew
3
On dirait que ça sub("^0+(?!$)", "", x, perl=TRUE)marchera aussi
Wiktor Stribiżew
2

Une autre regexoption:

^0*(.+)$

Voici une démo regex .

Utilisation base::subdans R:

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

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

Voici un R démo .

Ou développez la réponse de @ akrun :

sub("^$", "0", sub("^0+", "", c("005", "0AB", "000", "0")), perl = TRUE)
M--
la source