r之如何从右到左拆分字符串,如 Python 的 rsplit()

bhlsheji 阅读:58 2024-05-29 10:23:45 评论:0

假设一个向量:

xx.1 <- c("zz_ZZ_uu_d", "II_OO_d") 

我想从最右边分割一个新向量并且只分割一次。预期的结果是:
c("zz_ZZ_uu", "d", "II_OO", "d"). 

这就像 python 的 rsplit() 函数。我目前的想法是反转字符串,并在 str_split() 中用 stringr 分割。

有什么更好的解决方案吗?

更新
这是我的解决方案,返回 n 个拆分,具体取决于 stringr 和 stringi。有人提供具有基本功能的版本会很好。
rsplit <- function (x, s, n) { 
  cc1 <- unlist(stringr::str_split(stringi::stri_reverse(x), s, n)) 
  cc2 <- rev(purrr::map_chr(cc1, stringi::stri_reverse)) 
  return(cc2) 
} 

请您参考如下方法:

负前瞻:

unlist(strsplit(xx.1, "_(?!.*_)", perl = TRUE)) 
# [1] "zz_ZZ_uu" "d"        "II_OO"    "d"      

其中 a(?!b) 说要找到这样一个 a ,它后面没有 b 。在这种情况下 .*_ 意味着无论多远( .* )都不应该有更多的 _

然而,概括这个想法似乎并不容易。首先,请注意它可以用 _(?=[^_]*$) 重写为正向前瞻(找到 _ 后跟除 _ 之外的任何内容,这里 $ 表示字符串的结尾)。那么一个不太优雅的概括将是
rsplit <- function(x, s, n) { 
  p <- paste0("[^", s, "]*") 
  rx <- paste0(s, "(?=", paste(rep(paste0(p, s), n - 1), collapse = ""), p, "$)") 
  unlist(strsplit(x, rx, perl = TRUE)) 
} 
 
rsplit(vec, "_", 1) 
# [1] "a_b_c_d_e_f" "g"           "a"           "b"           
rsplit(vec, "_", 3) 
# [1] "a_b_c_d" "e_f_g"   "a_b"     

哪里例如如果 n=3 此函数使用 _(?=[^_]*_[^_]*_[^_]*$)


标签:Python
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号