regsub -all和proc

时间:2012-08-24 12:47:23

标签: regex recursion tcl proc

我正在编写一个名为“subliner3”的递归过程。简单来说,它取代了:

  1. [object method]Object->method()
  2. [object method:attr1 attr2 ...]object->method(attr1,attr2,...)
  3. 在(2)中替换(1)和(2)是递归的。任何attr可能类似于(1)或(2)。

    因此,此代码会导致问题:

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

    这应该在子行中找到精确的(2)(子行是属性列表)并再次为它调用函数。问题是,当用regsub的\ 1调用子行时,\ subliner3真的得到“\ 1”和“\ 2”,所以看起来他们被解释为subliner3调用。如何设置调用[subliner3“\ 1”“\ 2”]并解释为\ 1& \ 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);
    

2 个答案:

答案 0 :(得分:0)

可能的解决方案之一是: expr \“[regsub -all {(1)}”number 1“”[getSp \ 1]“] \” 所以,起初,regsub设法将(1)置于\ 1位置。然后expr调用getSp。它将被称为不是\ 1,而是(1)。 但是为了使用这个解决方案,我需要确保,regsub返回的字符串[]只为程序指定了[,但它不是那样的。例如,regsub调用之后的字符串可能是这样的: [self runAction:[CCSequence actions:[subliner3“CCDelayTime actionWithDuration”“5”],[subliner3“CCCallFunc actionWithTarget”“self selector:@selector(resetMessage)”],nil]]; 只有subliner3 - 是一个程序。

答案 1 :(得分:0)

你可以这样做(在某些假设下,例如不使用数组),但你真的需要在内部工作并将你的替换代码放在一个循环中。

# 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 \001stripExtra stuff\002, 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 \\3\u0002)" 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,所以你应该检查它的实际输入数据的输出是否合理......