Obtendo e removendo o primeiro caractere de uma string

102

Eu gostaria de fazer algumas caminhadas bidimensionais usando cadeias de caracteres, atribuindo valores diferentes a cada personagem. Eu estava planejando 'estourar' o primeiro caractere de uma string, usá-lo e repetir para o resto da string.

Como posso conseguir algo assim?

x <- 'hello stackoverflow'

Eu gostaria de ser capaz de fazer algo assim:

a <- x.pop[1]

print(a)

'h'
print(x)

'ello stackoverflow'
pedrosaurio
fonte

Respostas:

167

Veja ?substring.

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

A ideia de ter um popmétodo que retorna um valor e tem um efeito colateral de atualizar os dados armazenados xé muito mais um conceito da programação orientada a objetos. Portanto, em vez de definir uma popfunção para operar em vetores de caracteres, podemos fazer uma classe de referência com um popmétodo.

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"
Algodão rico
fonte
15

Também existe str_subdo pacote stringr

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

Use esta função do stringipacote

> x <- 'hello stackoverflow'
> stri_sub(x,2)
[1] "ello stackoverflow"
Bartektartanus
fonte
8

substringé definitivamente melhor, mas aqui está uma strsplitalternativa, já que ainda não vi uma.

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

ou equivalente

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

E você pode pastejuntar o resto da corda.

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

removendo os primeiros caracteres:

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

A ideia é selecionar todos os caracteres, começando de 2 a um número de caracteres em x. Isso é importante quando você tem um número desigual de caracteres em uma palavra ou frase.

Selecionar a primeira letra é trivial como respostas anteriores:

substring(x,1,1)
Jon
fonte
2

Outra alternativa é usar a captura de subexpressões com as funções de expressão regular regmatchese regexec.

# the original example
x <- 'hello stackoverflow'

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

Isso retorna a string inteira, o primeiro caractere e o resultado "exibido" em uma lista de comprimento 1.

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

que é equivalente a list(c(x, substr(x, 1, 1), substr(x, 2, nchar(x)))). Ou seja, ele contém o superconjunto dos elementos desejados, bem como a string inteira.


Adicionar sapplypermitirá que esse método funcione para um vetor de caracteres de comprimento> 1.

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

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

Isso retorna uma lista com a string completa correspondente como o primeiro elemento e as subexpressões correspondentes capturadas por ()como os seguintes elementos. Portanto, na expressão regular '(^.)(.*)', (^.)corresponde ao primeiro caractere e (.*)aos caracteres restantes.

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

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

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

Agora, podemos usar o método trusty sapply+ [para extrair as substrings desejadas.

myFirstStrings <- sapply(myStrings, "[", 2)
myFirstStrings
[1] "h" "r" "a"
mySecondStrings <- sapply(myStrings, "[", 3)
mySecondStrings
[1] "ello stackoverflow" "ight back"          "t yah"
lmo
fonte
Este é um truque muito bom, mas acho que não atende à questão.
pedrosaurio
Você precisará explicar melhor, pois isso pode produzir a mesma saída que as outras respostas. Veja o bloco final de código que usa sapplypara a extração. "popping" o primeiro caractere, conforme especificado na pergunta, é uma questão de repetir esse processo no vetor resultante (mySecondStrings).
lmo de
Claro que funciona com a explicação extra que você acabou de adicionar, mas ainda acho que é mais complicado do que deveria.
pedrosaurio