0

我正在使用 PEG(Ruby 的柑橘实现)制作 bbcode 解析器,但我一直在解析这个[b]sometext[anothertext[/b]

有代码

grammar BBCodeParser
  rule document
    (open_tag | close_tag | new_line | text)*
  end
  rule open_tag
    ("[" tag_name "="? tag_data? "]")
  end

  rule close_tag
    ("[/" tag_name "]") 
  end

  rule text
    [^\n\[\]]+
  end

  rule new_line
    ("\r\n" | "\n")
  end

  rule tag_name
    # [p|br|b|i|u|hr|code|quote|list|url|img|\*|color]
    [a-zA-Z\*]+
  end

  rule tag_data
    ([^\[\]\n])+
  end
end

问题在于text我不知道怎么说的规则,该文本可以包含除 \r、\n、open_tag 或 close_tag 之外的所有内容。使用此实现,由于排除 [ 和 ],它在示例中失败(那是错误的)

所以最后的问题是如何做规则,它可以匹配除 \r、\n 或 open_tag 或 close_tag 的完全匹配之外的任何内容

如果您有另一个 PEG 实施的解决方案,也可以在那里提供。我可以切换:)

4

3 回答 3

0

[当不是另一个标签的开始时,这将解析任何文本并递归地继续。

rule text
    [^\n\[\]]+ (!open_tag text)?
end
于 2011-09-19T16:00:22.843 回答
0

rule text
    [^\n\[\]]+ (!open_tag text)?
end

以解析错误结束

我试图继续这个想法,结果是([^\n] (!open_tag | !close_tag) text*) 但它也会失败。它会匹配"sometext[anothertext[/b]"

查找临时解决方案 ((!open_tag | !close_tag | !new_line) .) 它只会一个字母一个字母地找到,但忽略所有打开和关闭标签。我可以稍后将这些字母组合在一起 :)

于 2011-09-19T20:57:06.433 回答
0

不久前我遇到了类似的问题。有一个技巧可以做到这一点:
你需要说 match open_tag,然后是不是结束标签的所有内容,然后是closing_tag。所以这给出了以下规则

rule tag
  open_tag ((!open_tag | !close_tag | !new_line ) .)+ close_tag
end
于 2012-07-23T21:12:10.147 回答