我一直在考虑使用Scala的解析器组合库(基本上是PEG解析器)编写一个Textile解析器,并且想知道我应该使用哪种方法来解析内联修饰符
This is *bold* text, _italic_ text, +underlined+ text, etc.
在这种情况下,它非常清楚什么是什么,应该解析什么。但是,有很多边缘情况并不那么清楚。只关注粗体文字:
Which sections get bolded:
*onomato*poeia* ?
bold *word*, without a space after?
tyr*annos*aurus
a bold word in a (*bracket*)?
How about *This *case?
显然,这是主观(事情应该算作粗体)和客观(如何使解析规则正确解析)的混合。
我倾向于选择像
这样的PEGwordChar = [a-zA-Z]
nonWordChar = [^a-zA-Z]
boldStart = nonWordChar ~ * ~ wordChar
boldEnd = wordChar ~ * ~ nonWordChar
boldSection = boldStart ~ rep(not(boldEnd) ~ anyChar) ~ boldEnd
将解析上述内容如下:
<b>onomato*poeia</b> ?
bold <b>word</b>, without a space after?
tyr*annos*aurus <- fails because of lack of whitespace
a bold word in a (<b>bracket</b>)?
How about *This *case? <- fails because there is no correct closing *
但是,我不确定这种方法是否适用于所有用例,并且适用于所有边缘情况。有没有一种标准的方法可以复制和依赖?如果我能避免的话,我宁可不要依赖我的特殊思维方式。
答案 0 :(得分:1)
在降价的情况下没有标准,并且边缘情况的实现不同。对于markdown的一组选择,您可以查看peg-markdown,它也用于MultiMarkdown。当然,降价在这方面比纺织品更复杂,因为它使用**
表示粗体,*
表示斜体,从而产生更多关于如何对待*hello**there**
之类的事情的决定。
PHP markdown extra的开发人员Michel Fortin有test suite,其中包含大量粗体/斜体的边缘情况。但是,我不认为他的决定在这里有普遍的一致意见,并且许多实现解析不同。
那就是说,我认为以下决定在降价方面毫无争议:
*
仅在下一个字符为非空格时才开始强调。*
只会结束强调。he*ll*o
中,两个l被强调(尽管一些降价实现为_
字符禁用此功能,因为下划线在标识符中很常见。)答案 1 :(得分:0)
在采购一段时间后,我找到了inline markup recognition rules for reStructuredText。
它不遵循降价规则;特别是像t*hi*s
这样的东西不会被解析为内联标签,但它非常相似,并且具有类似的总体目的。
这也是一个有点复杂的规范(例如,带有括号和标点符号的特殊外壳)但它的指定非常明确,经过彻底解释和证明。我发现它的规格是建立起来的坚实基础。