在 Java 中解析 YAML 前端
Posted
技术标签:
【中文标题】在 Java 中解析 YAML 前端【英文标题】:Parsing YAML Front matter in Java 【发布时间】:2012-07-30 23:43:21 【问题描述】:我必须在java
中解析YAML Front Matter
,比如jekyll
,所以我查看了源代码和found this,但我无法理解它(我不太了解红宝石)。
所以我的问题是,如何在 java 中解析 YAML Front Matter
?
我的类路径中有snakeyaml,我将从降价文件中解析YAML Front Matter
,为此我使用pegdown
【问题讨论】:
有几个可用于 java 的 YAML 库,snakeyaml 就是其中之一。那么你从前端读取 YAML 到底有什么问题呢? 我的问题是如何将 YAML 前端内容与 markdown 分开并安全解析? 【参考方案1】:void parse(Reader r) throws IOException
BufferedReader br = new BufferedReader(r);
// detect YAML front matter
String line = br.readLine();
while (line.isEmpty()) line = br.readLine();
if (!line.matches("[-]3,")) // use at least three dashes
throw new IllegalArgumentException("No YAML Front Matter");
final String delimiter = line;
// scan YAML front matter
StringBuilder sb = new StringBuilder();
line = br.readLine();
while (!line.equals(delimiter))
sb.append(line);
sb.append("\n");
line = br.readLine();
// parse data
parseYamlFrontMatter(sb.toString());
parseMarkdownOrWhatever(br);
要获得Reader
,您可能需要FileReader
或InputStreamReader
。
【讨论】:
来吧@Arian,这比一个正则表达式的例子要低,如果用户使用超过 3 个-
或少于 3 个 -
或者如果第一行只是一个空行,然后 yaml 开始,这一切都用正则表达式很容易,但我正在寻找比正则表达式更可靠的东西。
格式规范(1) 明确指出第一行正好包含三个破折号。 (1)github.com/mojombo/jekyll/wiki/YAML-Front-Matter
遗憾的是我无法应用该限制
更新了我的答案。根据您的输入,您可能希望将 equals(delimiter)
替换为另一个 matches
@Gautam K:根据规范,当它是 YAML 时,您的第一条评论中的所有情况都不会发生。根据规范,YAML front matter 必须在文件的开头,必须以三个破折号开头并以它结尾。其他一切都是可选的。【参考方案2】:
好的,因为您的评论澄清了您的问题:
yaml 前面的内容是包含三个破折号 (---
) 的行内的所有内容。
YAML Front matter 总是在文件的开头。
因此,您只需解析文件并从文件开头提取 YAML Front Matter。您可以使用自动机或正则表达式对其进行解析。这真的取决于你。它的结构总是相同的:
--- 这里有一些 YAML --- Markdown / Textile / html 文件内容【讨论】:
我了解正则表达式方法,但如果可能的话,我会尽量避免这种情况。那么我该如何使用automaton
它就像你可以编写的每个解析器。读一行。如果是---
,则将 bool 切换为 true 并开始将 YAMl 写入缓冲区。如果你再次点击 `---` 将 bool 切换为 false 并停止写入缓冲区。然后你的缓冲区包含所有 YAML。只需确保仅在文件开头检测即可。这真的非常微不足道,提供代码示例意味着发布一个完整的、有效的解决方案。而且我认为这不是 SO 的目的。
我不熟悉写解析器。
我给了你一个完整的指令,你只需要写实际的代码(我不会,不管你设置多高的赏金)。也许您可以解释一下您在编写代码时的实际问题是什么?
我写代码没有问题,只是我不知道从哪里开始写解析器。【参考方案3】:
如果你只是对前面的事情感兴趣,可以使用SnakeYaml的loadAll方法:
Object yamlFrontMatter(Yaml yaml, InputStream in)
return yaml.loadAll().iterator().next();
SnakeYaml 只会读取第一个 yaml 结构(前面的内容)并忽略尾随的非 yaml 文本。
不幸的是,SnakeYaml 没有优雅的方式来输出剩余的文本,所以如果你想同时解析前端和正文,这种方式没有优势:-(
【讨论】:
以上是关于在 Java 中解析 YAML 前端的主要内容,如果未能解决你的问题,请参考以下文章