Abrufen und Entfernen des ersten Zeichens einer Zeichenfolge

101

Ich möchte einige zweidimensionale Spaziergänge mit Zeichenketten durchführen, indem ich jedem Zeichen unterschiedliche Werte zuweise. Ich hatte vor, das erste Zeichen einer Zeichenfolge zu "platzen", es zu verwenden und für den Rest der Zeichenfolge zu wiederholen.

Wie kann ich so etwas erreichen?

x <- 'hello stackoverflow'

Ich möchte in der Lage sein, so etwas zu tun:

a <- x.pop[1]

print(a)

'h'
print(x)

'ello stackoverflow'
pedrosaurio
quelle

Antworten:

166

Siehe ?substring.

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

Die Idee, eine popMethode zu haben, die sowohl einen Wert zurückgibt als auch einen Nebeneffekt beim Aktualisieren der darin gespeicherten Daten hat, xist ein Konzept der objektorientierten Programmierung. Anstatt eine popFunktion für die Bearbeitung von Zeichenvektoren zu definieren, können wir mit einer Methode eine Referenzklassepop erstellen.

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"
Richie Cotton
quelle
15

Es gibt auch str_subaus dem stringr-Paket

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

Verwenden Sie diese Funktion aus dem stringiPaket

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

substringist definitiv das Beste, aber hier ist eine strsplitAlternative, da ich noch keine gesehen habe.

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

oder gleichwertig

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

Und Sie können pasteden Rest der Saite wieder zusammenfügen.

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

erste Zeichen entfernen:

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

Die Idee ist, alle Zeichen von 2 bis zur Anzahl der Zeichen in x auszuwählen. Dies ist wichtig, wenn Sie eine ungleiche Anzahl von Zeichen in Wörtern oder Phrasen haben.

Die Auswahl des ersten Buchstabens ist als vorherige Antwort trivial:

substring(x,1,1)
jon
quelle
2

Eine andere Alternative ist die Erfassung von Unterausdrücken mit den Funktionen für reguläre Ausdrücke regmatchesund regexec.

# the original example
x <- 'hello stackoverflow'

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

Dies gibt die gesamte Zeichenfolge, das erste Zeichen und das Ergebnis "popped" in einer Liste mit der Länge 1 zurück.

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

das ist äquivalent zu list(c(x, substr(x, 1, 1), substr(x, 2, nchar(x)))). Das heißt, es enthält die Supermenge der gewünschten Elemente sowie die vollständige Zeichenfolge.


Durch Hinzufügen sapplykann diese Methode für einen Zeichenvektor mit einer Länge> 1 verwendet werden.

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

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

Dies gibt eine Liste mit der übereinstimmenden vollständigen Zeichenfolge als erstem Element und den übereinstimmenden Unterausdrücken zurück, die von ()den folgenden Elementen erfasst werden . So in dem regulären Ausdruck '(^.)(.*)', (^.)entspricht das erste Zeichen und (.*)entspricht die restlichen Zeichen.

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

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

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

Jetzt können wir die Trusty sapply+ [-Methode verwenden, um die gewünschten Teilzeichenfolgen herauszuziehen.

myFirstStrings <- sapply(myStrings, "[", 2)
myFirstStrings
[1] "h" "r" "a"
mySecondStrings <- sapply(myStrings, "[", 3)
mySecondStrings
[1] "ello stackoverflow" "ight back"          "t yah"
lmo
quelle
Dies ist ein sehr schöner Trick, aber ich denke, das lässt die Frage aus.
Pedrosaurio
Sie müssen dies weiter erläutern, da es die gleiche Ausgabe wie die anderen Antworten erzeugen kann. Siehe den letzten Codeblock, der sapplyfür die Extraktion verwendet wird. Beim "Poppen" des ersten Zeichens, wie in der Frage angegeben, wird dieser Vorgang für den resultierenden Vektor (mySecondStrings) wiederholt.
lmo
Sicher, es funktioniert mit der zusätzlichen Erklärung, die Sie gerade hinzugefügt haben, aber ich finde es immer noch komplizierter als es sollte.
Pedrosaurio