R - 字符串操作和提取

R - string manipulation and extraction

我有一个字符串 strEx <- "list(A, B, C, D)",我想将其存储为字符向量:

[1] "A" "B" "C" "D"

我不太擅长正则表达式(也可能有点矫枉过正,但将来我会需要更多)这可能是我问题的一部分。我有一个解决方案,我觉得 code/bad 形式太多了。

它最终给了我想要的东西,但我仍然需要用逗号分隔它并将它展平。我只是觉得这是一种过于粗糙的方法。谁有更好的解决方案?

d <- gsub(".*\((.*)\).*", "\1", strEx)
d1 <- unlist(tstrsplit(d, ", ", type.convert = TRUE, fixed = TRUE))

您可以尝试使用 eval(parse(...)),为每个字母添加引号:

unlist(eval(parse(text=gsub("([A-Z])", "\"\1\"", "list(A, B, C, D)"))))
#[1] "A" "B" "C" "D"

如果第一个字符串中没有逗号,您可以添加逗号并使用另一个 sub 步骤删除最后一个逗号:

unlist(eval(parse(text=sub(",(?=[)])", "", gsub("([A-Z])", "\"\1\",", "list(A B C D)"), perl=TRUE))))
# [1] "A" "B" "C" "D"

您的两步法非常好且可读性强。如果你想尝试一次性 抓取文本块中的项目 ,你可以使用带有 \G\K 运算符的 PCRE 正则表达式,使用基本 R函数:

> g <- unlist(regmatches(strEx, gregexpr("(?:list\(\s*|(?!^)\G(?:,\s*)?)\K[^,)]+", strEx, perl=TRUE)))
> g
[1] "A" "B" "C" "D"

图案详情:

  • (?:list\(\s*|(?!^)\G(?:,\s*)?) - list( 和 0+ 空格子字符串(参见 list\(\s* 部分)或上一次成功匹配的结尾(参见 (?!^)\G)和可选, 和零个或多个空格的序列(参见 (?:,\s*)?
  • \K - 省略目前匹配的文本
  • [^,)]+ - ,).
  • 以外的 1 个或多个字符

参见regex demo online

您可以像这样解析表达式:

#parse the expression
pEx <- parse(text = strEx)[[1]] 

表达式实际上是符号列表,可以这样处理。这里我们把除list以外的所有字符都变成字符:

vapply(pEx[-1], as.character, FUN.VALUE = "")
#[1] "A" "B" "C" "D"

但是,如果您需要解析字符串(这也是您提出的使用正则表达式的解决方案),通常应该改进前面的一些步骤。您不应该有需要解析的表达式。

看到这个:

library(fortunes)
fortune(106)
#If the answer is parse() you should usually rethink the question.
#   -- Thomas Lumley
#      R-help (February 2005)