Lấy và xóa ký tự đầu tiên của một chuỗi


101

Tôi muốn thực hiện một số bước đi 2 chiều bằng cách sử dụng các chuỗi ký tự bằng cách gán các giá trị khác nhau cho mỗi ký tự. Tôi đã định 'bật' ký tự đầu tiên của một chuỗi, sử dụng nó và lặp lại cho phần còn lại của chuỗi.

Làm thế nào tôi có thể đạt được một cái gì đó như thế này?

x <- 'hello stackoverflow'

Tôi muốn có thể làm điều gì đó như sau:

a <- x.pop[1]

print(a)

'h'
print(x)

'ello stackoverflow'

Câu trả lời:


166

Thấy chưa ?substring.

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

Ý tưởng về một popphương thức vừa trả về một giá trị vừa có tác dụng phụ là cập nhật dữ liệu được lưu trữ trong đó xlà một khái niệm từ lập trình hướng đối tượng. Vì vậy, thay vì xác định một pophàm để hoạt động trên các vectơ ký tự, chúng ta có thể tạo một lớp tham chiếu với một popphương thức.

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

Cũng có str_subtừ gói stringr

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

10

Sử dụng chức năng này từ stringigói

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

8

substringchắc chắn là tốt nhất, nhưng đây là một giải strsplitpháp thay thế, vì tôi chưa thấy một lựa chọn nào.

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

hoặc tương đương

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

Và bạn có thể quay pastelại phần còn lại của chuỗi với nhau.

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

5

xóa các ký tự đầu tiên:

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

Ý tưởng là chọn tất cả các ký tự bắt đầu từ 2 đến số ký tự trong x. Điều này rất quan trọng khi bạn có số lượng ký tự trong từ hoặc cụm từ không bằng nhau.

Chọn chữ cái đầu tiên là không đáng kể như các câu trả lời trước:

substring(x,1,1)

2

Một giải pháp thay thế khác là sử dụng bắt các biểu thức phụ với các hàm biểu thức chính quy regmatchesregexec.

# the original example
x <- 'hello stackoverflow'

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

Điều này trả về toàn bộ chuỗi, ký tự đầu tiên và kết quả "bật lên" trong danh sách có độ dài 1.

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

tương đương với list(c(x, substr(x, 1, 1), substr(x, 2, nchar(x)))). Nghĩa là, nó chứa tập siêu các phần tử mong muốn cũng như chuỗi đầy đủ.


Việc thêm sapplysẽ cho phép phương thức này hoạt động đối với vectơ ký tự có độ dài> 1.

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

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

Điều này trả về một danh sách với chuỗi đầy đủ phù hợp làm phần tử đầu tiên và các biểu thức phụ phù hợp được ghi lại ()dưới dạng các phần tử sau. Vì vậy, trong biểu thức chính quy '(^.)(.*)', (^.)khớp với ký tự đầu tiên và (.*)khớp với các ký tự còn lại.

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

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

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

Bây giờ, chúng ta có thể sử dụng phương thức trusty sapply+ [để lấy ra các chuỗi con mong muốn.

myFirstStrings <- sapply(myStrings, "[", 2)
myFirstStrings
[1] "h" "r" "a"
mySecondStrings <- sapply(myStrings, "[", 3)
mySecondStrings
[1] "ello stackoverflow" "ight back"          "t yah"

Đây là một thủ thuật rất hay nhưng tôi nghĩ rằng nó đã bỏ lỡ câu hỏi.
pedrosaurio

Bạn sẽ cần giải thích thêm vì nó có thể tạo ra kết quả tương tự như các câu trả lời khác. Xem khối mã cuối cùng được sử dụng sapplyđể trích xuất. "popping" ký tự đầu tiên, như được chỉ định trong câu hỏi, là vấn đề lặp lại quá trình này trên vectơ kết quả (mySecondStrings).
lmo

Chắc chắn nó hoạt động với phần giải thích bổ sung mà bạn vừa thêm vào nhưng tôi vẫn thấy nó phức tạp hơn mức cần thiết.
pedrosaurio
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.