lark文法:转义字符串正则表达式是如何工作的?

2024-09-21 03:18:39 发布

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

lark解析器预定义了一些常见的终端,包括一个字符串。其定义如下:

_STRING_INNER: /.*?/
_STRING_ESC_INNER: _STRING_INNER /(?<!\\)(\\\\)*?/ 

ESCAPED_STRING : "\"" _STRING_ESC_INNER "\""

我确实明白。我也理解ESCAPED_STRING是如何组成的。但我真正不明白的是_STRING_ESC_INNER

如果我读对了正则表达式,它所说的就是,每当我发现两个连续的文本反斜杠时,它们不能被另一个文本反斜杠所取代

我如何将这两个组合成一个正则表达式

语法不需要在字符串数据中只允许转义双引号吗


Tags: 数据字符串文本终端解析器string定义语法
1条回答
网友
1楼 · 发布于 2024-09-21 03:18:39

预备工作:

  • .*?非贪婪匹配,表示.(任何符号)的最短重复次数。这只有在后面跟着其他东西时才有意义。因此,输入AAXAAX上的.*?X将只匹配AAX部分,而不是一直扩展到最后一个X

  • (?<!...)是一个“反向查找后断言”(link):“如果字符串中的当前位置前面没有匹配…,则匹配”。因此.*(?<!X)Y将匹配AY,而不是XY

将此应用于您的示例:

  • ESCAPED_STRING:规则说:“匹配",然后_STRING_ESC_INNER,然后再"

  • _STRING_INNER:匹配任何符号的最短重复次数。如前所述,这只有在考虑后面的正则表达式时才有意义

  • _STRING_ESC_INNER:我们希望它匹配不包含结束引号的尽可能短的字符串。也就是说,对于输入"abc"xyz",我们希望匹配"abc",而不是同时使用xyz"部分。然而,我们必须确保"实际上是一个结束语,因为它本身不应该被转义。因此,对于输入"abc\"xyz",我们不希望只匹配"abc\",因为\"是转义的。我们注意到,结束"之前必须有一个偶数\(零是偶数)。所以"是可以的,\\"是可以的,\\\\"是可以的,等等。但是只要"前面有一个奇数\,这意味着"实际上不是一个结束引号

    (\\\\)匹配\\。{}表示“以前的职位不应该有{}”。因此,组合的(?<!\\)(\\\\)表示“匹配\\,但前提是它前面没有\

    下面的*?然后进行尽可能小的重复,这同样只有在考虑后面的正则表达式时才有意义,这是来自ESCAPED_STRING规则的"(可能的混淆点:ESCAPED_STRING中的\"指的是文字"在我们想要匹配的实际输入中,以相同的方式\\\\引用输入中的\\)。因此(?<!\\)(\\\\)*?\"意味着“匹配紧跟在"后面而不紧跟在\前面的最短数量的\\。换句话说,(?<!\\)(\\\\)*?\"只匹配前面有偶数个\"(包括大小为0的块)

    现在将它与前面的_STRING_INNER结合起来,_STRING_ESC_INNER规则说:匹配前面有偶数个\的第一个",换句话说,第一个"中的\本身并没有转义。

相关问题 更多 >

    热门问题