我想在字符串列中提取第一个点之前的字符。我可以使用下面的代码。虽然,代码似乎过于复杂,我不得不诉诸for-loop
。有没有更简单的方法?我特别感兴趣的是regex
解决方案。
请注意,查找每个字符串中的最后一个数字对我的实际数据不起作用,尽管这种方法适用于此示例。
感谢您的任何建议。
my.data <- read.table(text = '
my.string state
......... A
1........ B
112...... C
11111.... D
1111113.. E
111111111 F
111111111 G
', header = TRUE, stringsAsFactors = FALSE)
desired.result <- c(NA,1,2,1,3,NA,NA)
识别第一个点的位置:
my.data$first.dot <- apply(my.data, 1, function(x) {
as.numeric(gregexpr("\\.", x['my.string'])[[1]])[1]
})
拆分字符串:
split.strings <- t(apply(my.data, 1, function(x) { (strsplit(x['my.string'], '')[[1]]) } ))
my.data$revised.first.dot <- ifelse(my.data$first.dot < 2, NA, my.data$first.dot-1)
提取第一个点之前的字符:
for(i in 1:nrow(my.data)) {
my.data$character.before.dot[i] <- split.strings[i,my.data$revised.first.dot[i]]
}
my.data
# my.string state first.dot revised.first.dot character.before.dot
# 1 ......... A 1 NA <NA>
# 2 1........ B 2 1 1
# 3 112...... C 4 3 2
# 4 11111.... D 6 5 1
# 5 1111113.. E 8 7 3
# 6 111111111 F -1 NA <NA>
# 7 111111111 G -1 NA <NA>
以下是相关帖子:
答案 0 :(得分:4)
使用以下正则表达式,不要忘记启用perl=TRUE
参数。
^[^.]*?\K[^.](?=\.)
在R中,正则表达式就像,
^[^.]*?\\K[^.](?=\\.)
> library(stringr)
> as.numeric(str_extract(my.data$my.string, perl("^[^.]*?\\K[^.](?=\\.)")))
[1] NA 1 2 1 3 NA NA
模式说明:
^
断言我们刚开始。[^.]*?
任何角色的非贪婪匹配,直到第一个点。\K
丢弃之前匹配的字符。[^.]
我们要匹配的角色不能是一个点。(?=\.)
此字符必须后跟一个点。因此它匹配之前存在的字符到第一个点。答案 1 :(得分:3)
最简单的正则表达式是^([^.])+(?=\.)
:
^ # Start of string
( # Start of group 1
[^.] # Match any character except .
)+ # Repeat as many times as needed, overwriting the previous match
(?=\.) # Assert the next character is a .
第1组的内容将是您想要的角色。我不是一个R家伙,但根据RegexBuddy,以下内容应该有效:
matches <- regexpr("^([^.])+(?=\\.)", my.data, perl=TRUE);
result <- attr(matches, "capture.start")[,1]
attr(result, "match.length") <- attr(matches, "capture.length")[,1]
regmatches(my.data, result)
答案 2 :(得分:3)
在示例中,全部是digits
和.
library(stringr)
as.numeric(str_extract(my.data$my.string, perl('\\d(?=\\.)')))
#[1] NA 1 2 1 3 NA NA
或使用stringi
library(stringi)
as.numeric(stri_extract(my.data$my.string, regex='\\d(?=\\.)'))
#[1] NA 1 2 1 3 NA NA
如果是general
案例:
as.numeric(str_extract(my.data$my.string, perl('[^.](?=\\.)')))
答案 3 :(得分:2)
答案 4 :(得分:2)
以下是ifelse
的基本R解决方案:
res <- regexpr("[^.](?=\\.)", my.data$my.string, perl = TRUE)
ifelse(res < 1, NA, as.integer(regmatches(my.data$my.string, res)))
# [1] NA 2 1 3 1 NA NA
答案 5 :(得分:1)
使用rex可能会使这类任务变得更简单。
my.data <- read.table(text = '
my.string state
......... A
1........ B
112...... C
11111.... D
1111113.. E
111111111 F
111111111 G
', header = TRUE, stringsAsFactors = FALSE)
library(rex)
re_matches(my.data$my.string,
rex(capture(except(".")), "."))$'1'
#> [1] NA "1" "2" "1" "3" NA NA