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

问题描述 投票:1回答:1

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

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

ESCAPED_STRING : "\"" _STRING_ESC_INNER "\""

我了解_STRING_INNER。我也了解ESCAPED_STRING的组成。但是我不太了解的是_STRING_ESC_INNER

如果我正确阅读了正则表达式,它的意思是,每当我发现两个连续的文字反斜杠时,它们都不能以另一个文字反斜杠开头吗?

如何将这两个合并为一个正则表达式?

并且是否不要求语法只允许在字符串数据中使用转义的双引号?

regex grammar lark-parser
1个回答
0
投票

初步:

  • .*?非贪心匹配,表示.(任何符号)的最短重复次数。这仅在后面有其他内容时才有意义。因此,输入.*?X上的AAXAAX仅匹配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)时才有意义。因此,(?<!\\)(\\\\)*?\"的意思是“匹配最短的\\数量,后跟\"且不以\开头。换句话说,(?<!\\)(\\\\)*?\"仅匹配以偶数开头的\" \(包括大小为0的块)。

    现在将其与前面的_STRING_INNER组合在一起,然后_STRING_ESC_INNER规则说:匹配first

    \"并加上偶数个\,也就是说,第一个\" \本身未转义的位置。
© www.soinside.com 2019 - 2024. All rights reserved.