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'

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"

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"

10

Verwenden Sie diese Funktion aus dem stringiPaket

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

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"

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)

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"

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.