首页 > 解决方案 > 通过计算特定字符来子集字符串

问题描述

我有以下字符串:

strings <- c("ABBSDGNHNGA", "AABSDGDRY", "AGNAFG", "GGGDSRTYHG") 

我想切断字符串,只要 A、G 和 N 的出现次数达到某个值,比如 3。在这种情况下,结果应该是:

some_function(strings)

c("ABBSDGN", "AABSDG", "AGN", "GGG") 

我尝试使用stringi,stringr和正则表达式,但我无法弄清楚。

标签: rregexgsubstringrstringi

解决方案


str_extract您可以通过从stringr包中进行简单调用来完成您的任务:

library(stringr)

strings <- c("ABBSDGNHNGA", "AABSDGDRY", "AGNAFG", "GGGDSRTYHG")

str_extract(strings, '([^AGN]*[AGN]){3}')
# [1] "ABBSDGN" "AABSDG"  "AGN"     "GGG"

正则表达式模式的[^AGN]*[AGN]一部分表示要查找零个或多个不是 A、G 或 N 的连续字符,然后是 A、G 或 N 的一个实例。用括号和大括号的附加包装,像这样([^AGN]*[AGN]){3},意味着看对于该模式连续三次。您可以通过更改花括号中的整数来更改要查找的 A、G、N 的出现次数:

str_extract(strings, '([^AGN]*[AGN]){4}')
# [1] "ABBSDGNHN"  NA           "AGNA"       "GGGDSRTYHG"

有几种方法可以使用基本 R 函数来完成您的任务。一种是使用regexpr后跟regmatches

m <- regexpr('([^AGN]*[AGN]){3}', strings)
regmatches(strings, m)
# [1] "ABBSDGN" "AABSDG"  "AGN"     "GGG"

或者,您可以使用sub

sub('(([^AGN]*[AGN]){3}).*', '\\1', strings)
# [1] "ABBSDGN" "AABSDG"  "AGN"     "GGG"

推荐阅读