我试图通过分析R历史来整理一个跟踪对象历史的小脚本。我坚持有效地解析R命令并拆分它们。请考虑以下R命令:
for( i in 1:10 ) { a[i] <- myfunc() ; print( sprintf( "done step %d; proceeding", i ) ) }
以分号或大括号分割不是问题,但是引号中的分号(或其他特殊事物)呢?我最终通过char去查询char并跟踪我是否在引用中(以及反斜杠......)。这是步法,我确信有一些更简单的东西,可能是在Unix诞生的时候发明的。一个聪明的正则表达式,也许?
答案 0 :(得分:5)
使用parse
。它返回一个表达式,可以将其子集化到解析树的各个组件中:
x <- parse(text='for( i in 1:10 ) { a[i] <- myfunc() ; print( sprintf( "done step %d; proceeding", i ) ) }',n=1)
x[[1]]
for (i in 1:10) {
a[i] <- myfunc()
print(sprintf("done step %d; proceeding", i))
}
x[[1]][[1]]
`for`
x[[1]][[4]]
{
a[i] <- myfunc()
print(sprintf("done step %d; proceeding", i))
}
x[[1]][[4]][[2]]
a[i] <- myfunc()
答案 1 :(得分:3)
这取决于您需要多少详细信息,但除了基本parse
功能之外,您还可以查看真正快速完成其工作的真棒parser
包,并返回更多详细信息到parse
。快速演示:
> library(parser)
> parser(text='for( i in 1:10 ) { a[i] <- myfunc() ; print( sprintf( "done step %d; proceeding", i ) ) }')
expression(for (i in 1:10) {
a[i] <- myfunc()
print(sprintf("done step %d; proceeding", i))
})
attr(,"data")
line1 col1 byte1 line2 col2 byte2 token id parent top_level token.desc terminal text
1 1 0 0 1 3 3 270 1 77 0 FOR TRUE for
2 1 3 3 1 4 4 40 2 77 0 '(' TRUE (
3 1 5 5 1 6 6 263 4 77 0 SYMBOL TRUE i
4 1 7 7 1 9 9 271 6 77 0 IN TRUE in
5 1 10 10 1 11 11 261 8 9 0 NUM_CONST TRUE 1
6 1 10 10 1 11 11 78 9 15 0 expr FALSE
7 1 11 11 1 12 12 58 10 15 0 ':' TRUE :
8 1 12 12 1 14 14 261 11 12 0 NUM_CONST TRUE 10
9 1 12 12 1 14 14 78 12 15 0 expr FALSE
10 1 15 15 1 16 16 41 14 77 0 ')' TRUE )
11 1 10 10 1 14 14 78 15 77 0 expr FALSE
12 1 17 17 1 18 18 123 18 74 0 '{' TRUE {
13 1 19 19 1 20 20 263 20 22 0 SYMBOL TRUE a
14 1 20 20 1 21 21 91 21 28 0 '[' TRUE [
15 1 19 19 1 20 20 78 22 28 0 expr FALSE
16 1 21 21 1 22 22 263 23 25 0 SYMBOL TRUE i
17 1 22 22 1 23 23 93 24 28 0 ']' TRUE ]
18 1 21 21 1 22 22 78 25 28 0 expr FALSE
19 1 19 19 1 23 23 78 28 40 0 expr FALSE
20 1 24 24 1 26 26 265 30 40 0 LEFT_ASSIGN TRUE <-
21 1 27 27 1 33 33 297 32 34 0 SYMBOL_FUNCTION_CALL TRUE myfunc
22 1 33 33 1 34 34 40 33 37 0 '(' TRUE (
23 1 27 27 1 33 33 78 34 37 0 expr FALSE
24 1 34 34 1 35 35 41 35 37 0 ')' TRUE )
25 1 27 27 1 35 35 78 37 40 0 expr FALSE
26 1 36 36 1 37 37 59 39 74 0 ';' TRUE ;
27 1 19 19 1 35 35 78 40 74 0 expr FALSE
28 1 38 38 1 43 43 297 44 46 0 SYMBOL_FUNCTION_CALL TRUE print
29 1 43 43 1 44 44 40 45 69 0 '(' TRUE (
30 1 38 38 1 43 43 78 46 69 0 expr FALSE
31 1 45 45 1 52 52 297 48 50 0 SYMBOL_FUNCTION_CALL TRUE sprintf
32 1 52 52 1 53 53 40 49 64 0 '(' TRUE (
33 1 45 45 1 52 52 78 50 64 0 expr FALSE
34 1 54 54 1 80 80 260 52 54 0 STR_CONST TRUE "done step %d; proceeding"
35 1 80 80 1 81 81 44 53 64 0 ',' TRUE ,
36 1 54 54 1 80 80 78 54 64 0 expr FALSE
37 1 82 82 1 83 83 263 58 61 0 SYMBOL TRUE i
38 1 84 84 1 85 85 41 60 64 0 ')' TRUE )
39 1 82 82 1 83 83 78 61 64 0 expr FALSE
40 1 45 45 1 85 85 78 64 69 0 expr FALSE
41 1 86 86 1 87 87 41 66 69 0 ')' TRUE )
42 1 38 38 1 87 87 78 69 74 0 expr FALSE
43 1 89 89 1 90 90 125 71 74 0 '}' TRUE }
44 1 17 17 1 90 90 78 74 77 0 expr FALSE
45 1 0 0 1 90 90 78 77 0 0 expr FALSE