按条件应用 strsplit

Apply strsplit by conditional

我尝试应用以下规则:

将字符串截断 ; 以达到最大长度 n

例如,

n <- 4
string <- c("a;a;aabbbb;ccddee;ff")
output <- c("a;a;", "aabb", "bb;", "ccdd", "ee;", "ff")

对于"aabb",由于切分长度"aabbbb"超过n = 4,所以按长度切分,4.

对于"bb;",由于斩波长度"bb;" < 4,我们接下来考虑"bb;ccddee"。但是,下一个 chop 的长度超过了 4,我们已经有 ; 存在于字符串中。因此,我们砍 ;.

目前,我可以通过Regex实现or

num <- 4
splitvar <- ";"

## splits pattern
pattern <- paste0("(?<=.{", num, "}|", splitvar, ")")

> pattern
[1] "(?<=.{4}|;)"

string <- c("a;a;aabbbb;ccddee;ff")
strsplit(string, pattern, perl = TRUE)
[[1]]
[1] "a;"   "a;"   "aabb" "bb;"  "ccdd" "ee;"  "ff"  

如您所见,我们实际上不需要切分 "a;""a;",因为长度不超过 n (2 + 2 = 4) .

有人对此有解决方案吗? 谢谢。

您的正则表达式匹配 splitvar 或前面至少有任何 num 个字符的位置。

您寻找的模式是一个正则表达式,匹配任何一个、两个或三个字符,然后是 splitvar 或除 splitvar 字符之外的任何 num 个字符。

所以,你可以使用

num <- 4
splitvar <- ";"
pattern <- paste0(".{1,", num-1, "}(?:",splitvar,"|$)|[^",splitvar,"]{",num,"}")
pattern ## => .{1,3}(?:;|$)|[^;]{4}
string <- c("a;a;aabbbb;ccddee;ff")
unlist(regmatches(string, gregexpr(pattern, string)))
## => "a;a;" "aabb" "bb;"  "ccdd" "ee;"  "ff" 

stringr:

library(stringr)
unlist(str_extract_all(string, pattern))

参见R demo online. See the regex demo

详情:

  • .{1,3}(?:;|$) - 一个、两个或三个字符(如果使用 stringr 则不包括换行符),然后是 ; 个字符或结尾字符串
  • | - 或
  • [^;]{4} - 除了 ; 字符之外的任意四个字符。