将字符按超过一个单词的方式拆分

4

我有以下这个字符:

endvotes <- "Yes106No85EH2NT6ES0P1"

我希望得到一个类似于这样的 data.frame
    Yes    No   EH   NT   ES  P
    106    85   2    6    0   1

我知道如何分割它们中的每一个,例如像这样:

yes <- unlist(str_split(end_votes, "\\No"))[1]
yes <- as.integer(unlist(str_split(yes, "Yes"))[2])

yes
[1] 106

我想一种可能性是按位置分割,但数字(一位、两位或三位)并不总是相同的,因此我想按答案(是、否等)进行分割。当然,我可以为每个答案做这个操作(如上所述),但我相信有一种更优雅的方式。

有人能告诉我怎么做得好看吗?

谢谢

4个回答

3
endvotes <- "Yes106No85EH2NT6ES0P1"

names <- strsplit(endvotes, "[[:digit:]]+")[[1]]
numbers <- strsplit(endvotes, "[[:alpha:]]+")[[1]][-1]

setNames(as.data.frame(t(as.numeric(numbers))), names)
#  Yes No EH NT ES P
#1 106 85  2  6  0 1

3

完全不需要使用正则表达式。尝试使用来自stringi包的此函数,它通过字符类(例如数字、字母或标点符号)来分割字符向量:

require(stringi)
stri_split_charclass(str=endvotes,"\\p{N}",omit_empty=T)[[1]]
## [1] "Yes" "No"  "EH"  "NT"  "ES"  "P"  
stri_split_charclass(str=endvotes,"\\p{L}",omit_empty=T)[[1]]
## [1] "106" "85"  "2"   "6"   "0"   "1"  

str只是一个向量,\p{N}\p{L}是您想要分割的类别(N代表数字,L代表字母)。使用omit_empty可以删除"" - 空字符串。


2

你可以使用这个正则表达式,每个匹配都会在第一个捕获组中拥有文本,第二个捕获组中拥有值:

([a-zA-Z]+)([0-9]+)

基本上这个正则表达式选择了一串字母,后面跟着一串数字。括号是捕获组,可以让你轻松地检索想要的值。
请参见此处演示

2
你可以尝试使用这个 正则表达式..
strsplit(endvotes, split = "(?<=[A-Za-z])(?=[0-9])|(?<=[0-9])(?=[A-Za-z])", perl = T)
## [[1]]
##  [1] "Yes" "106" "No"  "85"  "EH"  "2"   "NT"  "6"   "ES"  "0"   "P"   "1"  
##

为了获得所需的格式
S <- strsplit(endvotes, split = "(?<=[A-Za-z])(?=[0-9])|(?<=[0-9])(?=[A-Za-z])", perl = T)[[1]]
res <- data.frame(t(S[seq_along(S)%%2 == 0]))
names(res) <- t(S[seq_along(S)%%2 == 1])
res
##   Yes No EH NT ES P
## 1 106 85  2  6  0 1  

res <- data.frame(t(regmatches(endvotes, gregexpr("[0-9]+", endvotes))[[1]]))
names(res) <- t(regmatches(endvotes, gregexpr("[A-Za-z]+", endvotes))[[1]])
res
##   Yes No EH NT ES P
## 1 106 85  2  6  0 1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接