【发布时间】:2020-04-27 15:06:48
【问题描述】:
基本上正如标题所说,我有一个字符串向量,对于每个元素,我想提取第一个和第三个句点之间的所有内容。例如。
s <- c("random.0.0.word.1.0", "different.0.02.words.15.6", "different.0.1.words.4.2")
结果应该是:
"0.0" "0.02" "0.1"
【问题讨论】:
基本上正如标题所说,我有一个字符串向量,对于每个元素,我想提取第一个和第三个句点之间的所有内容。例如。
s <- c("random.0.0.word.1.0", "different.0.02.words.15.6", "different.0.1.words.4.2")
结果应该是:
"0.0" "0.02" "0.1"
【问题讨论】:
我们可以通过从字符串的开头 (^) 匹配不是 . ([^.]+) 的字符,然后是一个点 (\\.) 来捕获一个组,然后捕获它们之间的所有字符第一个和第三个点,在替换中使用捕获组((...))的反向引用(\\1)
sub("^[^.]+\\.([^.]+\\.[^.]+)\\..*", "\\1", s)
#[1] "0.0" "0.02" "0.1"
或者也可以在得到点的位置后用substr完成
lst1 <- gregexpr('.', s, fixed = TRUE)
substring(s, sapply(lst1, `[`, 1) + 1, sapply(lst1, `[`, 3) - 1)
#[1] "0.0" "0.02" "0.1"
【讨论】:
不使用任何花哨的正则表达式功能的另一种方法是拆分.,然后获取我们需要的位:
library(stringr)
library(purrr)
str_split(s, "\\.") %>%
map_chr(~ paste0(.[2:3], collapse = "."))
【讨论】:
我们可以使用sub 在第 1 和第 3 周期之间尽可能少地捕获。
sub(".*?\\.(.*?\\..*?)\\..*", "\\1", s)
#[1] "0.0" "0.02" "0.1"
【讨论】:
这是一种脱胶的方法,有些人可能会觉得不那么吓人:
library(unglue)
s <- c("random.0.0.word.1.0", "different.0.02.words.15.6", "different.0.1.words.4.2")
unglue_vec(s, "{=[^.]+}.{x}.{=[^.]+}.{=[^.]+}.{=[^.]+}")
#> [1] "0.0" "0.02" "0.1"
由reprex package (v0.3.0) 于 2020-01-16 创建
子模式[^.]+ 是“非点”序列,没有命名(= 的左侧没有任何名称),因为我们不想提取它们。
【讨论】: