在 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,您可能需要FileReaderInputStreamReader

【讨论】:

来吧@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 前端的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot解析指定Yaml配置文件

在保留注释的同时在 java 中修改 YAML

我如何在 Java 编程中验证 YAML 结构

在 Python 中解析 YAML 文件并访问数据?

如果有“!”,如何使用 PyYAML 解析 YAML在 YAML 中

在脚本中使用应用引擎 yaml 解析器