R - 字符串操作和提取

时间:2016-10-11 10:14:32

标签: r string gsub

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

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

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

它最终给了我想要的东西,但我仍然需要将它分成逗号并将其展平。我只觉得这是一个太粗糙的方式来解决它。任何人都有更漂亮的解决方案吗?

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

3 个答案:

答案 0 :(得分:3)

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

#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)

答案 1 :(得分:2)

您可以尝试使用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"

答案 2 :(得分:1)

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

> 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