带有正则表达式的字符串中第一个和最后一个非点的位置

时间:2015-03-24 09:44:59

标签: regex r string

我希望找到字符串的第一个和最后一个非点元素的位置。理想情况下,我希望在基座regex中使用R执行此操作。我已经编写了R代码来解决问题。但是,我对regex解决方案感兴趣。感谢您的任何建议。

以下是获取所需结果的示例数据集和R代码。此代码拆分字符串并使用which来定位每个非点的位置。然后,我使用minmax逐行获取aggregatemerge列。但是,我怀疑regex会更高效,更有趣。

my.data <- read.table(text = '
     my.string  state  cov
     11.......    A     1
     111......    A     2
     .1.1.....    B     3
     ....1....    B     4
     ..1.11...    C     5
     ...1.....    C     6
     .........    D     7
     .....1.1.    D     8    
', header = TRUE, stringsAsFactors = FALSE)

new.data  <- data.frame(do.call(rbind, strsplit(my.data$my.string,'')), my.data[,2:3], stringsAsFactors = FALSE)
new.data2 <- new.data[,1:9]

new.data2[new.data2 == '.'] <- NA

new.data2 <- t(apply(new.data2, 1, as.numeric))

not.NA <- as.data.frame(which(!is.na(new.data2), arr.ind = TRUE))

my.min.max3 <- with(not.NA, aggregate(not.NA$col, by = list(not.NA$row), FUN = function(x) c(MIN = min(x), MAX = max(x)) ))
my.min.max3 <- do.call(data.frame, my.min.max3)
colnames(my.min.max3) <- c('my.row', 'min', 'max')
my.min.max3

my.row <- 1:nrow(my.data)

my.output <- merge(my.row, my.min.max3, by.x=0, by.y = 'my.row', all=TRUE)
my.output <- my.output[,-1]
colnames(my.output) <- c('my.row', 'min', 'max')
my.output

#
#   my.row min max
# 1      1   1   2
# 2      2   1   3
# 3      3   2   4
# 4      4   5   5
# 5      5   3   6
# 6      6   4   4
# 7      7  NA  NA
# 8      8   6   8
#

3 个答案:

答案 0 :(得分:4)

你可以这样做,

> data.frame(my.data[,1], do.call(rbind, gregexpr("^\\.*\\K[^.]|[^.](?=\\.*$)", my.data[,1], perl=T)))
  my.data...1. X1 X2
1    11.......  1  2
2    111......  1  3
3    .1.1.....  2  4
4    ....1....  5  5
5    ..1.11...  3  6
6    ...1.....  4  4
7    ......... -1 -1
8    .....1.1.  6  8

答案 1 :(得分:2)

您可以尝试:

minmax <- t(sapply(my.data[,1], function(x) {
                                 y <- gregexpr("[^.]", x)[[1]]
                                 return(c(min=min(y), max=max(y)))}))
minmax[minmax==-1] <- NA

my.output <- data.frame(my.row=1:nrow(my.data), minmax)
#> my.output
#          my.row min max
#11.......      1   1   2
#111......      2   1   3
#.1.1.....      3   2   4
#....1....      4   5   5
#..1.11...      5   3   6
#...1.....      6   4   4
#.........      7  NA  NA
#.....1.1.      8   6   8

答案 2 :(得分:2)

我会使用stringi

对其进行矢量化
library(stringi)
cbind(my.data[1], with(my.data, 
                       cbind(min = stri_locate_first_fixed(my.string, "1")[, 1], 
                             max = stri_locate_last_fixed(my.string, "1")[, 2])))
#   my.string min max
# 1 11.......   1   2
# 2 111......   1   3
# 3 .1.1.....   2   4
# 4 ....1....   5   5
# 5 ..1.11...   3   6
# 6 ...1.....   4   4
# 7 .........  NA  NA
# 8 .....1.1.   6   8