【发布时间】:2022-12-10 03:05:09
【问题描述】:
考虑以下字符串:
x = "a (b, c), d [e, f (g, h)], i (j, k (l (m, n [o, p])))"
我的目标是获取此字符串并将其转换为以下列表:
list("a" = list("b", "c"),
"d" = list("e", "f" = list("g", "h")),
"i" = list("j", "k" = list("l" = list("m", "n" = list("o", "p")))))
$a
$a[[1]]
[1] "b"
$a[[2]]
[1] "c"
$d
$d[[1]]
[1] "e"
$d$f
$d$f[[1]]
[1] "g"
$d$f[[2]]
[1] "h"
$i
$i[[1]]
[1] "j"
$i$k
$i$k$l
$i$k$l[[1]]
[1] "m"
$i$k$l$n
$i$k$l$n[[1]]
[1] "o"
$i$k$l$n[[2]]
[1] "p"
第一个问题是尝试分离每个组件:
x = "a (b, c), d [e, f (g, h)], i (j, k (l (m, n [o, p])))"
str_split_quotes = function(s) {
o = el(strsplit(s, split = "(?<=\\)|\\]),", perl = T))
lapply(o, function(z) gsub(pattern = " ", "", z))
}
str_unparse_level = function(s) {
check_parsed = function(s) {
grepl("\\)|\\]", s)
}
parse = function(s) {
if (check_parsed(s)) {
substring_name = substr(s, 1, 1)
substring_content = substr(s, 3, nchar(s) - 1)
substring_content_split = el(strsplit(substring_content, ",(?![^()]*+\\))", perl = T))
o = list(substring_content_split)
names(o) = substring_name
return(o)}
else {return(s)}
}
lapply(s, parse)
}
str_unparse_level(str_split_quotes(x))
[[1]]
[[1]]$a
[1] "b" "c"
[[2]]
[[2]]$d
[1] "e" "f(g,h)"
[[3]]
[[3]]$i
[1] "j" "k(l(m,n[o,p]))"
直观地,这里需要发生的是某种涉及递归的函数(由于圆括号/方括号的嵌套深度可变)需要在这里执行,以便创建一个列表,正如我在上面寻求的那样。鉴于我很少使用递归,我不清楚该怎么做。
【问题讨论】:
-
你不需要递归。这是一个与“表达式中的平衡括号”相关的已知问题。该方法是遍历您的字符串并将左括号 - ( 和 [ - 放在堆栈中,当您到达右括号时,您处理堆栈中右括号和最后一个左括号之间的表达式。如此直到堆栈空。然后你进一步遍历字符串并处理下一个表达式。在你的情况下,堆栈可能是一个具有两个字段的对象 - 左括号和它后面的部分字符串。
标签: r