regsub -all and proc



我正在编写一个递归过程,称为"subliner3"。简单地说,它取代了

  1. [object method]Object->method()
  2. [object method:attr1 attr2 ...]object->method(attr1,attr2,...)

在(2)中替换(1)和(2)是递归的。任何attr都可以类似于(1)或(2)。

所以,这个代码导致了问题:

while {[regsub -all {[([^[]:]+)[:]([^[]]+)]} $subline "[subliner3 "\1" "\2"]" subline]} {}

这应该在子行中精确地找到(2)(子行是一个属性列表),并再次为其调用函数。问题是,当用regsub的\1和\2子行3调用子行时,它们确实得到了"\1"one_answers"\2",所以看起来它们是在调用子行3之后被解释的。我如何用解释的\1&调用[subliner3"\1"\2"]\2.

样本输入:

[self runAction:[CCSequence actions:[CCDelayTime actionWithDuration:5], [CCCallFunc actionWithTarget:self selector:@selector(resetMessage)], nil]]; 

输出:

self->runAction(CCSequence::actions(CCDelayTime::actionWithDuration(5), CCCallFunc::actionWithTarget(self, @selector(resetMessage)), nil);

您可以做到这一点(在某些假设下,例如不使用数组),但您确实需要从内到外工作,并将替换代码放入循环中。

# Your sample as input
set string {[self runAction:[CCSequence actions:[CCDelayTime actionWithDuration:5], [CCCallFunc actionWithTarget:self selector:@selector(resetMessage)], nil]];}
# Do most of the replacements, recursively.
#
# Note that some parts are changed to 01stripExtra stuff02, because we need
# to do further processing on the arguments which can't quite be done in this
# looped [regsub].
while {[regsub -all {[(w+) (w+):([^]]+)]} $string 
        "\1::\2(u0001stripExtra \3u0002)" string]} {}
# The further processing to do on arguments (removing selectors)
proc stripExtra args {
    foreach s $args {
        # The lack of a fourth argument means [regsub] returns the string
        lappend t [regsub {^w+:(?!:)} [string trimright $s ","] {}]
    }
    return [join $t ","]
}
# Apply the further processing by converting to a substitutable string
set string [subst [string map {u0001 "[" u0002 "]"} $string]]
# Now transformed...
puts $string

上面的代码相当脆弱,因为它实际上并不理解Objective-C,所以你应该检查它的输出在你的真实输入数据上是否合理…

一种可能的解决方案是:expr\"[regsub-all{(1)}"number 1"[getSp\1]"]\"因此,一开始,regsub设法将(1)置于\1位置。然后expr调用getSp。它将不是用\1调用,而是用(1)调用。但为了使用这个解决方案,我需要确保regsub返回的字符串[]只为过程指定,但并非总是这样。例如,regsub调用后的字符串可能如下所示:[self-runAction:[CSequence actions:[subliner3"CCDelayTime actionWithDuration"5"],[subliner3"CCCallFunc actionWithTarget"self-selector:@selector(resetMessage)"],nil]]其中只有subliner3-是一个过程。

最新更新