我需要匹配key = value
BibTeX 文件中对的值,这些文件可以包含任意嵌套的大括号,由大括号分隔。我最多匹配两个深嵌套的花括号,就像{some {stuff} like {this}}
kludgey一样:
token brace-value {
'{' <-[{}]>* ['{' <-[}]>* '}' <-[{}]>* ]* '}'
}
Run Code Online (Sandbox Code Playgroud)
我对再往下一层的想法感到不寒而栗……但是正确解析我的 BibTeX 内容至少需要三层深。
是的,我知道周围有 BibTeX 解析器,但我需要获取完整的条目以进行进一步处理,同时查看几个键。我的*.bib
文件相当温和(我不介意手动处理一些杂散条目),问题是我有很多文件,并且有很多重叠。但是一些“相同”的条目有不同的键,或者额外的数据。我想将它们合并成几个主文件(BibTeX 背后的整个想法,对吧?)。如果bibtool
给出一个没有重复(ha!)大约 20,000 行的文件,手工就不好玩了...
在仔细阅读了 Lenz 的“使用 Perl 6 正则表达式和语法解析”(Apress,2017 年)之后,我意识到“正则表达式”机制(基于回溯)实际上可能比官方承认的更强大,因为正则表达式可以调用另一个,并且我在任何地方都没有看到禁止递归调用。
在深入研究之前,先了解一些上下文无关的语法:描述嵌套大括号(没有别的)的一种方法是使用语法:
S -> { S } S | <无>
即,嵌套大括号要么是左大括号,要么是嵌套大括号,要么是右大括号,要么是更多嵌套的大括号;或者什么都没有。这或多或少直接转换为 Raku(没有空的正则表达式,通过使构造可选来伪造它):
my regex nb {
[ '{' <nb> '}' <nb> ]?
}
Run Code Online (Sandbox Code Playgroud)
瞧,这行得通。需要修复以避免捕获,终止回溯(如果它在第一次尝试时不匹配,则永远不会匹配),并用“其他任何”填充物进行装饰。
my regex nested-braces {
:ratchet
<-[{}]>*
[ '{' <.nested-braces> '}' <.nested-braces> ]?
<-[{}]>*
};
Run Code Online (Sandbox Code Playgroud)
这检查了我的测试用例。
对于不太喜欢冒险的人,有Text::Balanced
Perl 模块(以前是 Perl 5,可以从 Raku 使用 调用Inline::Perl5
)。不幸的是,在语法中对我没有直接用处。
好的,刚刚(重新)检查过。的文档'{' ~ '}'
还有很多不足之处,根本不清楚它是为了处理平衡的、正确嵌套的分隔符。
所以我的最终解决方案实际上就是这样:
my regex nested-braces {
:ratchet
'{' ~ '}' .*
}
Run Code Online (Sandbox Code Playgroud)
感谢大家!今天学到了不少东西。