【问题标题】:Regex re.sub on file font matter [duplicate]关于文件字体问题的正则表达式 re.sub [重复]
【发布时间】:2020-01-27 09:11:26
【问题描述】:

我试图从.md 文件中检索前文,当我的前文的每个标题都在一行时,我可以检索内容。

例如:

---
title: "Meeting"
date: 2019-03-14T07:51:28+01:00
draft: false
status:["process", "todo"]
---

所以我写了下面的python脚本来获取前文内容

def get_front_matter(file, start='---', end='---'):
    """Strip file and retrieve front matter then format the value"""
    content = {}
    with open(file, 'r', encoding='UTF-8') as file_content:
        for content_line in file_content:
            if content_line.strip() == start:
                break
        for content_line in file_content:
            if content_line.strip() == end:
                break

            line_data = content_line.split(':', 1)
            # If we cannot split decently, carry on
            if len(line_data) != 2:
                continue
            # format the string to store in dict for better usage
            content[line_data[0]] = re.sub(r"[\n\t]*", "", line_data[1]).strip(' "')
    return content

但是,如果我的前任 status 有多行,我会遇到问题。

---
title: "Meeting"
date: 2019-03-14T07:51:28+01:00
draft: false
status:
  [
    "process",
    "todo",
    "hold"
  ]
---

当我尝试阅读上述文件的前面事项时,我得到一个空白值到status,但它应该如下:

{'title': 'Meeting', 'date': '2019-03-14T07:51:28+01:00', 'draft': 'false', 'teams': '["process", "todo", "hold"]'}

有没有其他方法可以根据行或标签来读取前文的内容。我尝试了一些正则表达式,但我无法检索一组行。

【问题讨论】:

  • 前面的内容通常采用一种通用格式,并且您的标题看起来很像 YAML。你确定需要手动解析吗?
  • 我没有任何选择,因为 md 文件已经生成,我现在无法更改它们:(
  • 我问的是header是否 YAML,而不是你能不能改成它。
  • 是的。我现在也在尝试其他解决方案elbauldelprogramador.com/en/…
  • 如果是 yaml,您可以将虚线之间的位分开并将其提供给 pyyaml。

标签: python regex python-3.x


【解决方案1】:

我几乎保留了你的代码,关键是 在我们之前不要将值添加到结果中 确保我们收集了完整的value(当它被分成多行时),这是通过验证下一个str 行来完成的,如果它是一个有效值(key: some value) 然后添加上一个key结果是content,或者是结尾字符---,我希望cmets让事情更清楚

    def get_front_matter(file, start='---', end='---'):
        """Strip file and retrieve front matter then format the value"""
        result = {}
        with open(file, 'r', encoding='UTF-8') as file_content:
            for content_line in file_content:
                if content_line.strip() == start:
                    break

            content = ''
            key = ''
            for content_line in file_content:
                if content_line.strip() == end:
                    if key and content:
                        # add last key: content before breaking out
                        result[key] = re.sub(r"[\n\t]*", "", content).strip (' "')
                    break

                line_data = content_line.split(':', 1)
                if len(line_data) == 2 and not content:
                    # this is our first key: content, in this point we don't have previous content so we should keep them and check the next value first
                    key = line_data[0]
                    content = line_data[1]
                    continue
                elif len(line_data) == 2:  # we found another valid value 
                    # add previous (key, content) and keep the new (key , content)
                    result[key] = re.sub(r"[\n\t]*", "", content).strip(' "')
                    key = line_data[0]
                    content = line_data[1]
                else:
                    # not a valid key: value add it to previous value because it's a value splited in multiple line
                    content += content_line

        return result

注意:我用结果更改了内容名称,此代码将因以下情况而中断:

     title: "Meeting"
    date: 2019-03-14T07:51:28+01:00
    draft: false
    status:
      [
        "somevalue:process",  # if the value contains ':'
        "todo",
        "hold"
      ]

在这里,您没有指定我们如何区分键和包含 ':' 的值(如果它前面没有键)。我希望这不会使 给你一个问题

【讨论】:

  • 很棒的@CharifDZ。谢谢你。我花了一点时间来理解逻辑,但它是完美的。万分感谢。!希望这对其他人也有帮助..
猜你喜欢
  • 2011-11-14
  • 2017-12-03
  • 2019-08-27
  • 2016-02-08
  • 1970-01-01
  • 2016-12-22
  • 1970-01-01
  • 2020-07-01
  • 2020-12-23
相关资源
最近更新 更多