0

我正在尝试做一个简单的 VB6 到 c 的翻译器来帮助我将开源游戏移植到 c 语言。我希望能够使用 ragex 从“With Npclist[NpcIndex]”中获取“NpcList[NpcIndex]”,并在需要替换的任何地方替换它。(“With”在 VB6 中用作宏,在需要时添加 Npclist[NpcIndex] 直到找到“End With”)

Example:
 With Npclist[NpcIndex]
 .goTo(245) <-- it should be replaced with Npclist[NpcIndex].goTo(245)
 End With

是否可以使用正则表达式来完成这项工作?我尝试使用函数在“With”和“End With”之间执行另一个正则表达式替换,但我不知道“With”正在替换的文本(Npclist [NpcIndex])。提前致谢

4

3 回答 3

1

我个人不会相信任何单一的正则表达式解决方案可以在第一次就正确完成,也不想调试它。相反,我会逐行解析代码并缓存任何With表达式以使用它来替换任何.直接位于前面的空格或任何类型的括号(根据需要添加用例):

(?<=[\s[({])\.- 对集合中的任何字符进行正向回溯 + 转义的文字点

(?:(?<=[\s[({])|^)\..- 如果要替换可能出现在行首,则使用此非捕获替代列表

import re

def convert_vb_to_c(vb_code_lines):
    c_code = []
    current_with = ""
    for line in vb_code_lines:
        if re.search(r'^\s*With', line) is not None:
            current_with = line[5:] + "."
            continue
        elif re.search(r'^\s*End With', line) is not None:
            current_with = "{error_outside_with_replacement}"
            continue
        line = re.sub(r'(?<=[\s[({])\.', current_with, line)
        c_code.append(line)
    return "\n".join(c_code)


example = """
With Npclist[NpcIndex]
    .goTo(245)
End With
With hatla
    .matla.tatla[.matla.other] = .matla.other2
    dont.mind.me(.do.mind.me)
    .next()
End With
"""
# use file_object.readlines() in real life
print(convert_vb_to_c(example.split("\n")))
于 2013-04-22T20:19:45.440 回答
0

您可以将函数传递给该sub方法:

# just to give the idea of the regex
regex = re.compile(r'''With (.+)
(the-regex-for-the-VB-expression)+?
End With''')

def repl(match):
    beginning = match.group(1)  # NpcList[NpcIndex] in your example
    return ''.join(beginning + line for line in match.group(2).splitlines())

re.sub(regex, repl, the_string)

repl您可以从对象中获取有关匹配的所有信息match,构建您想要的任何字符串并返回它。匹配的字符串将被您返回的字符串替换。

请注意,您必须非常小心地编写regex上述内容。特别是(.+)像我一样使用将所有行匹配到排除的换行符,这可能不是你想要的(但我不知道 VB,我不知道哪个正则表达式可以去那里而不是只捕获你想要的东西。

对于(the-regex-forthe-VB-expression)+. 我不知道这些行中可能包含什么代码,因此我将实现它的细节留给您。也许把所有的行都写好是可以的,但我不相信这么简单的东西(可能表达式可以跨越多行,对吧?)。

通常,在一个大的正则表达式中完成所有操作通常容易出错且速度慢。

我强烈认为正则表达式只是为了查找WithEnd With使用其他东西来进行替换。

于 2013-04-22T18:59:00.013 回答
0

这可能会满足您在 Python 2.7 中的需求。我假设你想去掉Withand End With,对吧?你不需要 C 中的那些。

>>> import re
>>> search_text = """
... With Np1clist[Npc1Index]
...  .comeFrom(543)
... End With
...
... With Npc2list[Npc2Index]
...  .goTo(245)
... End With"""
>>>
>>> def f(m):
...     return '{0}{1}({2})'.format(m.group(1), m.group(2), m.group(3))
...
>>> regex = r'With\s+([^\s]*)\s*(\.[^(]+)\(([^)]+)\)[^\n]*\nEnd With'
>>> print re.sub(regex, f, search_text)

Np1clist[Npc1Index].comeFrom(543)

Npc2list[Npc2Index].goTo(245)
于 2013-04-22T21:37:32.037 回答