flo*_*wit 4 python regex grammar lark-parser
Lark 解析器预定义了一些常见的终端,包括一个字符串。它的定义如下:
_STRING_INNER: /.*?/
_STRING_ESC_INNER: _STRING_INNER /(?<!\\)(\\\\)*?/
ESCAPED_STRING : "\"" _STRING_ESC_INNER "\""
Run Code Online (Sandbox Code Playgroud)
我明白_STRING_INNER。我也明白ESCAPED_STRING是如何组成的。但我真的不明白的是_STRING_ESC_INNER。
如果我正确阅读了正则表达式,它只是说每当我找到两个连续的文字反斜杠时,它们前面不能有另一个文字反斜杠?
如何将这两者组合成一个正则表达式?
语法是否只需要在字符串数据中允许转义双引号?
预赛:
.*?非贪婪匹配,意味着.(任何符号)的最短可能重复次数。这只有在后面跟着其他东西时才有意义。因此.*?X,输入AAXAAX将仅匹配AAX部分,而不是一直扩展到最后一个X.
(?<!...)是一个“否定后视断言”(链接):“如果字符串中的当前位置前面没有匹配......则匹配”。所以.*(?<!X)Y会匹配AY但不会XY。
将此应用于您的示例:
ESCAPED_STRING:规则说:“匹配",然后_STRING_ESC_INNER,然后"再”。
_STRING_INNER: 匹配任何符号的最短可能重复次数。如前所述,这仅在考虑后面的正则表达式时才有意义。
_STRING_ESC_INNER:我们希望它匹配不包含结束引号的最短字符串。也就是说,对于 input "abc"xyz",我们想要匹配"abc",而不是同时消耗xyz"部分。但是,我们必须确保"确实是一个结束语,因为它本身不应该被转义。所以对于 input "abc\"xyz",我们不想只匹配"abc\",因为\"被转义了。我们观察到收盘"必须直接在偶数之前\(零是偶数)。所以"可以,\\"可以,\\\\"可以等等。但是只要"前面是奇数的\,就意味着"不是真正的结束语。
(\\\\)匹配\\。该(?<!\\)说“之前的位置不应该有\”。所以组合(?<!\\)(\\\\)意味着“匹配\\,但前提是它前面没有\”。
然后,下面*?会尽可能地重复 this,这再次仅在考虑后面的正则表达式时才有意义,即"fromESCAPED_STRING规则(可能的混淆点:\"inESCAPED_STRING指的是"实际输入中的文字,我们想要匹配,\\\\与\\在输入中引用的方式相同)。So 的(?<!\\)(\\\\)*?\"意思是“匹配\\后面是"而不是前面的最短数量\。换句话说,(?<!\\)(\\\\)*?\"只匹配"前面是偶数个\(包括大小为 0 的块)。
现在,它与前面的结合_STRING_INNER,该_STRING_ESC_INNER规则接着说:比赛中的第一个 "由偶数的前面\,所以换句话说,第一个"在\没有逃脱本身。
| 归档时间: |
|
| 查看次数: |
695 次 |
| 最近记录: |