我试图用python创建一个编译器,并使用re模块创建标记。语言将非常类似于Assembly
几乎所有的东西都在工作,但我有一个代币有问题。让我举一个例子说明这个代币是什么:

mov [eax], 4
mov [name],2
mov eax, [ebx]

令牌:[eax],[ebx]
我可以用这个模式找到我想要的:\[(eax|ebx)\]
但是当我和其他模式一起使用时,我得到了一个错误,我相信这是因为'|'。
SCANNER = re.compile(r"""
    ;(.)*                    # comment
    |(\[-?[0-9]+\])          # memory_int
    |(\[-?0x[0-9a-fA-F]+\])      # memory_hex
    |(\[(eax|ebx)\])             # memory access with registers
    """, re.VERBOSE)

for match in re.finditer(SCANNER, lines[i]):
            comment, memory_int, memory_hex, memory_reg = match.groups()

错误:
ValueError: too many values to unpack (expected 4)

有没有办法用另一个字符替换'|'

最佳答案

问题不在于:

    |(\[(eax|ebx)\])             # memory access with registers

这是因为表达式的这一部分定义了两个捕获组,一个嵌套在另一个组中,因此|返回的值比可以解包的多,例如第一行:
(None, None, None, '[eax]', 'eax')

避免嵌套组的一种方法是使用:
    |(\[eax\]|\[ebx\])          # memory access with registers

这将导致返回:
(None, None, None, '[eax]')

正如@Shashank所指出的,您还可以使用非捕获组match.groups()语法来定义嵌套的可能寄存器值模式:
    |(\[(?:eax|ebx)\])          # memory access with registers

为了达到同样的目的当可能的子模式数量较多(而且它们更复杂)时,这种方法是有利的,因为否则,您需要为每个可能完整地说明整个模式,而不是利用它们可能有的一些共性。

关于python - OR运算符内部的OR运算符-RegEX,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29932763/

10-11 03:52