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 个或多个字符
您可以像这样解析表达式:
#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)
我有一个字符串 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 个或多个字符
您可以像这样解析表达式:
#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)