regex - 在正则表达式或语法标记中捕获嵌套结构内的内容
问题描述
我想捕捉嵌套结构的内部。
my $str = "(a)";
say $str ~~ /"(" ~ ")" (\w) /;
say $str ~~ /"(" ~ ")" <(\w)> /;
say $str ~~ /"(" <(~)> ")" \w /;
say $str ~~ /"(" <(~ ")" \w /;
第一个有效;最后一个有效,但也捕获了右括号。另外两个失败,因此在这种情况下无法使用捕获标记。但是在语法的上下文中问题更加复杂,因为捕获组似乎也不起作用,就像这里:
# Please paste this together with the code above so that it compiles.
grammar G {
token TOP {
'(' ~ ')' $<content> = .+?
}
}
grammar H {
token TOP {
'(' ~ ')' (.+?)
}
}
grammar I {
token TOP {
'(' ~ ')' <( .+? )>
}
}
$str = "(one of us)";
for G,H,I -> $grammar {
say $grammar.parse( $str );
}
由于捕获分组或捕获标记似乎都不起作用,除非它被动态分配给变量。但是,这会创建一个我非常想避免的额外令牌。所以有两个问题
- 使捕获标记在嵌套结构中工作的正确方法是什么?
- 有没有办法使用捕获组或捕获标记中的标记来获取嵌套结构的内部?
解决方案
一个解决两个问题
根据 ugexe 的评论,
[...]
分组结构适用于您的所有用例。和捕获标记不是分组构造,因此除非它们被分组,否则它们不能与正则表达式
<(
操作一起使用。)>
~
上面最后两个要点中描述的行为并不明显,不在文档中,可能不符合设计文档,可能是烤洞,可能是我的想象等等。这个答案的其余部分解释了我对上述三个案例的发现,并讨论了一些可以做的事情。
油嘴滑舌的解释,仿佛一切都完美无缺
<(
并且)>
是捕获标记。
它们表现为零宽度断言。每个都断言“这标志着我想要为包含此标记的正则表达式捕获开始/结束的位置”。
根据正则表达式运算符的文档~
:
它主要忽略左参数,并对接下来的两个 [参数] 进行操作
(文档在我写“论点”的地方说“原子”。实际上它作用于接下来的两个原子或组。)
在正则表达式模式中"(" ~ ")" <(\w)>
:
")"
是 之后的第一个原子/组~
。<(
是 之后的第二个原子/组~
。~
忽略\w)>
。
解决方案是使用[...]
:
say '(a)' ~~ / '(' ~ ')' [ <( \w )> ] /; # 「a」
同样,在语法中:
token TOP { '(' ~ ')' [ <( .+? )> ] }
(...)
分组不是您想要的,原因有两个:
这不可能是你想要的。它将创建一个额外的
令牌捕获。你写道你想避免这种情况。即使您想要额外的捕获,
(...)
当棘轮有效时使用会在括号内夹住节俭的匹配。
捕获标记“不起作用”可以做些什么?
我认为文档更新可能是最好的选择。但是 imo 任何想提交关于某个问题或准备 PR 的人,都建议使用以下内容。
是否已知是预期行为或错误?
在 GH 存储库中搜索“捕获标记”:
术语“捕获标记”来自文档,而不是旧的设计文档,它只是说:
<(
令牌表示匹配的整体捕获的开始,而相应的令牌)>
表示其端点。.from
匹配时,它们表现为始终为真的断言,但具有设置匹配对象的和.to
属性的副作用。
(也许您可以从中找出要在问题等中搜索的字符串...)
在撰写本文时,所有 GH 都搜索<(
或)>
绘制空白,但这是由于当前内置 GH 搜索的弱点,而不是因为这些存储库中没有任何内容,例如this。
我很好奇并尝试了这个:
my $str = "aaa";
say $str ~~ / <(...)>* /;
它无限循环。*
只是作用)>
于. 这证实了捕获标记被视为原子的感觉。
正则表达式~
运算符适用于[...]
和其他一些分组的原子结构。解析它们中的任何一个在正则表达式模式中都有一个开始和结束。
捕获标记的不同之处在于它们不一定是配对的——开始或结束可以是隐含的。
鉴于 start ( /
or {
) 和 end ( /
or }
) 出现在俚语边界并且 Raku 是单通道解析编织,也许这使得 Raku 像我们希望的那样对待它们变得异常困难?
我认为文档修复可能是对您的 SO 的此捕获标记方面的适当响应。
如果 regex~
是唯一一个关心左右捕获标记都是一个单独的原子的 regex 构造,那么提到这个皱纹的最佳位置可能是在 regex~
部分。
但是考虑到多个正则表达式结构关心(量词根据上述无限循环示例执行),那么最好的地方可能是捕获标记部分。
或者,如果两者都提到它可能是最好的。(虽然这是一个滑坡......)
“不工作”可以做些什么:r (.*?)
?
我认为文档更新可能是最好的选择。但是 imo 任何想提交关于某个问题或准备 PR 的人,都建议使用以下内容。
是否已知是预期行为或错误?
搜索 GH 存储库ratchet frugal
:
术语“ratchet”和“frugal”都来自旧的设计文档,并且仍在最新的文档中使用,并且似乎没有别名。因此,对它们的搜索应该有望匹配所有相关提及。
上面的搜索是针对这两个词的。一次搜索一个可能会发现重要的相关提及,而碰巧没有提及另一个。
在撰写本文时,所有 GH 搜索.*?
或类似的绘制空白,但这是由于当前内置 GH 搜索的弱点,而不是因为这些存储库中没有任何内容。
也许这里的问题比棘轮、节俭和捕获的组合更广泛?
也许使用“棘轮”、“节俭”和“捕获”等词提出问题?
推荐阅读
- python - 在 TensorFlow 中构建模型时如何修复 ValueError?
- python - Pandas:如何对子类别中的前 N 个观察值进行子集化(和求和)?
- c# - 如何使用 SelectionUnit = Cell 取消选择 WPF DataGrid 中的选定单元格
- mongodb - MongoClient $in 不适用于 int 数组
- web - 我应该收取多少费用来使用 shopify 更新网站
- java - 像 C# 中的 cw 一样自动完成 System.out.println("")
- google-app-maker - APPMAKER - 多对多关系不起作用
- ssms-2012 - SQL Server 版本冲突
- r - 在 ggRGB 上叠加 ggR 栅格
- java - 在 docker 上运行的 https spring 应用程序