[英]R/Stringr Extract String after nth occurrence of "_" and end with first occurrence of "_"
使用 R 和 stringr package(或任何其他 package)
我想在第 n 次出现“_”后提取字符串,并以第一次出现“_”结束。
例如:
df <- c("J_J_HERE_jfdkaldjhieuwui","blahblah_ffd_THIS_fjdkalfj_jdka_")
我想要这个:
df_edited <- c("HERE","THIS")
或者对于这个例子,我想从“er”中提取一个空格后的所有内容,并以第一次出现的 _ 结尾:
df2 <- c("ex HERE_jfdkaldjhieuwui","ex_THIS_fjdkalfj_jdka_")
我想要这个:
df_edited <- c("HERE","THIS")
哪里有一个很好的备忘单来理解 stringr 条件,因为我很困惑。
我们可以创建一个基于“n”的模式
n <- 2
pat <- sprintf('([^_]+_){%d}([^_]+)_.*', n)
sub(pat, '\\2', df)
#[1] "HERE" "THIS"
细节 -
捕获一个或多个不是_
( [^_]+
) 的字符,后跟一个重复 'n' 次 (2) 的_
,然后是下一组不是_
( ([^_]+)
) 后跟一个_
和其他字符。 在替换中,指定第二个捕获组的反向引用
您可以在分隔符上拆分数据,以便所有单词都可用。
df <- c("J_J_HERE_jfdkaldjhieuwui","blahblah_ffd_THIS_fjdkalfj_jdka_")
list_word <- strsplit(df, '_')
list_word
#[[1]]
#[1] "J" "J" "HERE" "jfdkaldjhieuwui"
#[[2]]
#[1] "blahblah" "ffd" "THIS" "fjdkalfj" "jdka"
然后您可以从列表中获取 position n
处的任何值。
sapply(list_word, `[`, 3)
#[1] "HERE" "THIS"
sapply(list_word, `[`, 2)
#[1] "J" "ffd"
另一种选择是识别字符串中元素的 position。 此解决方案在此处针对类似问题进行了复制。 这有点乱,但它实现了我想要的,并且会解决你的问题。 我也喜欢我可以修改它以适应各种情况。 尽管如果我能理解正则表达式,它无疑会更干净、更高效。
下面的代码使用了以下的组合; stringr::str_locate_all()
输出列表列表,每个条目的矩阵 output 中的第一个“列”是模式每次出现的start
。 第二列是end
值。 因此,每个嵌入矩阵的每一行都包含模式的开始和结束位置。
由于我在 dataframe 中工作并且想要使用特定的索引号,我发现最简单的方法是提取与模式开始相关的数字并将其保存为 dataframe 中的变量。
purrr::map()
然后允许您提取特定值(在本例中为“n^th”)。我刚刚从每个值中提取了第二次出现(即第二行)的开始(即第一列)的索引矩阵.x[,1][2]
,在我的示例中)。 这个值然后需要是unlisted
,并存储为一个numeric
。
stringr::str_length()
然后返回字符串的 integer 长度(或“字符总数”)。
提取出具体的索引值后,需要从 position 提取一个 substring 到 position。记住特殊字符需要正确escaped
。
最后, stringr::str_sub()
提取特定模式第n'th
次出现和字符串中最后一个字符之间的所有内容。
text_pattern <- "-"
df <- data.table(var_name = c("kj<hdf - fæld - adsk-jf -h af",
"kj<hds - sdaf - saflaf- adf",
"asdgya - oaid - aa-s--s a-",
"k<hdfk - lkja - ljad -"))
df <- df %>%
mutate(second_dash = as.numeric(unlist
(str_locate_all(pattern = text_pattern, var_name) %>%
map(~ .x[,1][2])
)
)) %>%
mutate(New_substring = str_sub(string = var_name,
start = second_dash+2,
end = str_length(var_name)))
# var_name second_dash New_substring
# 1: kj<hdf - fæld - adsk-jf -h af 15 adsk-jf -h af
# 2: kj<hds - sdaf - saflaf- adf 15 saflaf- adf
# 3: asdgya - oaid - aa-s--s a- 15 aa-s--s a-
# 4: k<hdfk - lkja - ljad - 15 ljad -
对于您的特定情况,继续使用破折号而不是下划线,您可以使用变量指定索引号(或出现次数),例如n
和m
。
在下面的工作示例中,我在开头添加了 2,并从子字符串的末尾减去 2 以删除空格。 还应注意,索引包括所讨论的字符。 因此,如果您不希望 output 中包含破折号“-”或下划线“_”,则需要从提取的索引中至少减去或添加 1。 一切都取决于您的具体目的。 这也可以通过删除值周围的空格“填充”来更智能地实现,但我只是包括修改以说明如何操作索引值。
text_pattern <- "-"
n = 2
m = n + 1
df <- data.table(var_name = c("kj<hdf - fæld - adsk-jf -h af",
"kj<hds - sdaf - saflaf- adf",
"asdgya - oaid - aa-s--s a-",
"k<hdfk - lkja - ljad -"))
df <- df %>%
mutate(n_dash = as.numeric(unlist
(str_locate_all(pattern = text_pattern, var_name) %>%
map(~ .x[,1][n])
)
)) %>%
mutate(m_dash = as.numeric(unlist
(str_locate_all(pattern = text_pattern, var_name) %>%
map(~ .x[,1][m])
)
)) %>%
mutate(New_substring = str_sub(string = var_name,
start = n_dash+2,
end = m_dash-2))
# var_name New_substring n_dash m_dash
# 1: kj<hdf - fæld - adsk-jf -h af ads 15 21
# 2: kj<hds - sdaf - saflaf- adf safla 15 23
# 3: asdgya - oaid - aa-s--s a- a 15 19
# 4: k<hdfk - lkja - ljad - ljad 15 22
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.