Obtenir et supprimer le premier caractère d'une chaîne

102

Je voudrais faire des promenades en 2 dimensions en utilisant des chaînes de caractères en attribuant des valeurs différentes à chaque caractère. J'avais l'intention de «pop» le premier caractère d'une chaîne, de l'utiliser et de répéter pour le reste de la chaîne.

Comment puis-je réaliser quelque chose comme ça?

x <- 'hello stackoverflow'

J'aimerais pouvoir faire quelque chose comme ça:

a <- x.pop[1]

print(a)

'h'
print(x)

'ello stackoverflow'
pedrosaurio
la source

Réponses:

167

Voir ?substring.

x <- 'hello stackoverflow'
substring(x, 1, 1)
## [1] "h"
substring(x, 2)
## [1] "ello stackoverflow"

L'idée d'avoir une popméthode qui renvoie à la fois une valeur et a pour effet secondaire de mettre à jour les données stockées dans xest en grande partie un concept de la programmation orientée objet. Ainsi, plutôt que de définir une popfonction pour opérer sur des vecteurs de caractères, nous pouvons créer une classe de référence avec une popméthode.

PopStringFactory <- setRefClass(
  "PopString",
  fields = list(
    x = "character"  
  ),
  methods = list(
    initialize = function(x)
    {
      x <<- x
    },
    pop = function(n = 1)
    {
      if(nchar(x) == 0)
      {
        warning("Nothing to pop.")
        return("")
      }
      first <- substring(x, 1, n)
      x <<- substring(x, n + 1)
      first
    }
  )
)

x <- PopStringFactory$new("hello stackoverflow")
x
## Reference class object of class "PopString"
## Field "x":
## [1] "hello stackoverflow"
replicate(nchar(x$x), x$pop())
## [1] "h" "e" "l" "l" "o" " " "s" "t" "a" "c" "k" "o" "v" "e" "r" "f" "l" "o" "w"
Coton Richie
la source
15

Il y a aussi str_subdu package stringr

x <- 'hello stackoverflow'
str_sub(x, 2) # or
str_sub(x, 2, str_length(x))
[1] "ello stackoverflow"
Tony Ladson
la source
10

Utilisez cette fonction à partir du stringipackage

> x <- 'hello stackoverflow'
> stri_sub(x,2)
[1] "ello stackoverflow"
bartektartanus
la source
8

substringest certainement le meilleur, mais voici une strsplitalternative, car je n'en ai pas encore vu.

> x <- 'hello stackoverflow'
> strsplit(x, '')[[1]][1]
## [1] "h"

ou équivalent

> unlist(strsplit(x, ''))[1]
## [1] "h"

Et vous pouvez pasteremettre le reste de la chaîne ensemble.

> paste0(strsplit(x, '')[[1]][-1], collapse = '')
## [1] "ello stackoverflow"
Rich Scriven
la source
5

suppression des premiers caractères:

x <- 'hello stackoverflow'
substring(x, 2, nchar(x))

L'idée est de sélectionner tous les caractères de 2 au nombre de caractères en x. Ceci est important lorsque vous avez un nombre inégal de caractères dans un mot ou une phrase.

La sélection de la première lettre est triviale comme les réponses précédentes:

substring(x,1,1)
Jon
la source
2

Une autre alternative consiste à utiliser la capture de sous-expressions avec les fonctions d'expression régulière regmatcheset regexec.

# the original example
x <- 'hello stackoverflow'

# grab the substrings
myStrings <- regmatches(x, regexec('(^.)(.*)', x))

Cela renvoie la chaîne entière, le premier caractère et le résultat "popped" dans une liste de longueur 1.

myStrings
[[1]]
[1] "hello stackoverflow" "h"                   "ello stackoverflow" 

ce qui équivaut à list(c(x, substr(x, 1, 1), substr(x, 2, nchar(x)))). Autrement dit, il contient le super ensemble des éléments souhaités ainsi que la chaîne complète.


L'ajout sapplypermettra à cette méthode de fonctionner pour un vecteur de caractères de longueur> 1.

# a slightly more interesting example
xx <- c('hello stackoverflow', 'right back', 'at yah')

# grab the substrings
myStrings <- regmatches(x, regexec('(^.)(.*)', xx))

Cela renvoie une liste avec la chaîne complète correspondante comme premier élément et les sous-expressions correspondantes capturées par ()les éléments suivants. Donc, dans l'expression régulière '(^.)(.*)', (^.)correspond au premier caractère et (.*)correspond aux caractères restants.

myStrings
[[1]]
[1] "hello stackoverflow" "h"                   "ello stackoverflow" 

[[2]]
[1] "right back" "r"          "ight back" 

[[3]]
[1] "at yah" "a"      "t yah" 

Maintenant, nous pouvons utiliser la méthode trusty sapply+ [pour extraire les sous-chaînes souhaitées.

myFirstStrings <- sapply(myStrings, "[", 2)
myFirstStrings
[1] "h" "r" "a"
mySecondStrings <- sapply(myStrings, "[", 3)
mySecondStrings
[1] "ello stackoverflow" "ight back"          "t yah"
lmo
la source
C'est un truc très sympa mais je pense que ça passe à côté de la question.
pedrosaurio
Vous devrez expliquer plus en détail car cela peut produire le même résultat que les autres réponses. Voir le dernier bloc de code utilisé sapplypour l'extraction. "sauter" le premier caractère, comme spécifié dans la question, consiste à répéter ce processus sur le vecteur résultant (mySecondStrings).
lmo
Bien sûr, cela fonctionne avec l'explication supplémentaire que vous venez d'ajouter, mais je la trouve toujours plus compliquée qu'elle ne le devrait.
pedrosaurio