从字符串末尾分隔定界符固定次数

Jel*_*ina 3 regex r

我有一个数据帧如下:

df = data.frame(a = 1:4, strings = c('ooss_bboo_foo','ee_bbbbee_fffee','aas_baa_ffaa_daa', 'iisss_bbbbii_ffffii_dii_mii'))
Run Code Online (Sandbox Code Playgroud)

我想拆分_,生成新的列(或新的数据框,并不重要).可以用min(lengths(strsplit(df$strings, "_")))和估计出现的次数max(lengths(strsplit(df$strings, "_")))

期望的输出:

  X1                   X2       X3
1 ooss                 bboo     foo
2 ee                   bbbbee   fffee
3 aas_baa              ffaa     daa
4 iisss_bbbbii_ffffii  dii      mii
Run Code Online (Sandbox Code Playgroud)

我已经尝试了很多正则表达式,我已经非常绝望了......

G. *_*eck 5

以下是一些可能的解决方案:

1)gsubfn read.pattern包中的read.pattern可以直接生成数据帧结果.没有使用其他包.它使用特别简单的正则表达式.

首先我们创建模式,pat.例如,如果k3pat"(.*)_(.*)_(.*)".然后,只需运行read.pattern以生成结果data.frame:

library(gsubfn)

strings <- as.character(df$strings) # ensure it's character, not factor
k <- min(lengths(strsplit(strings, "_"))) # from question

pat <- paste(rep("(.*)", k), collapse = "_")
read.pattern(text = strings, pattern = pat, as.is = TRUE)
Run Code Online (Sandbox Code Playgroud)

赠送:

                   V1     V2    V3
1                ooss   bboo   foo
2                  ee bbbbee fffee
3             aas_baa   ffaa   daa
4 iisss_bbbbii_ffffii    dii   mii
Run Code Online (Sandbox Code Playgroud)

2)sub/read.table.相对于现有解决方案本解决方案涉及额外的步骤(该sub/ repl部分); 但是,它根本不使用任何包.它利用的strings,kpat从上面.在k等于3 的情况下,repl将是"\\1,\\2,\\3".

repl <- paste(paste0("\\", 1:k), collapse = ",")
read.table(text = sub(pat, repl, strings), sep = ",", as.is = TRUE)
Run Code Online (Sandbox Code Playgroud)

给出相同的结果.这两个实例","可以替换为数据中未找到的任何字符.

注意:在上面的解决方案中,我们习惯as.is = TRUE使输出列成为字符,但如果因子是正确的,则可以省略该参数.