Python复杂regex rep

2024-06-28 19:58:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试做一个简单的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”之间执行另一个regex replace,但我不知道“With”要替换的文本(Npclist[NpcIndex])。 提前谢谢


Tags: 语言游戏example地方withit开源end
3条回答

我个人不相信任何一个正则表达式解决方案能在第一次就搞定它,也不想调试它。相反,我将逐行解析代码并缓存任何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")))

这可以满足Python2.7中的需要。我假设你想去掉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)

可以将函数传递给^{}方法:

# 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,我不知道哪个regex可以去那里只捕捉您想要的内容。在

(the-regex-forthe-VB-expression)+也是如此。我不知道这些代码行中可能是什么代码,因此我把实现它的细节留给您。也许接受所有的行是可以的,但是我不相信这样简单的东西(表达式可能跨越多行,对吗?)。在

一般来说,在一个大型正则表达式中执行所有操作很容易出错,而且速度很慢。在

我强烈地考虑regex只为了找到With和{}并使用其他东西来进行替换。在

相关问题 更多 >