首页 > 解决方案 > 使用 Python 3 和 re.sub 将图像转换为 Base64 字符串,然后用循环中的编码字符串替换每个匹配的图像路径

问题描述

我正在使用 Python 3 将下面的 Markdown 转换为 HTML,但在此之前,我将引用的图像编码为 Base64 字符串。

我正在尝试使用 base64 编码的图像创建一个可移植的 HTML 文件,这样我就可以发送 HTML 而不必明确地将图像作为附件包含在内。

Lorem Ipsum Dolor Sit Amet

Image 1:
![](../attachments/image.png)

Lorem Ipsum Dolor Sit Amet

Image 2:
![](../attachments/image2.png)

我想出的代码如下:

import re
import base64
import os

# Variables:
folder = "/home/jake/notes/"
note = "note.md"

# Open Markdown note:
with open(note, "r") as note_file:

    # Read note contents into var:
    note_content = note_file.read()

    # Markdown image syntax regex:
    md_img_regex = r"!\[(.*?)\]\((.*?)\)"

    # Find all images in note:
    images = re.findall(md_img_regex, note_content)

    # Actions if images are found in note:
    if images:

        # Loop through regex matches:
        for image in images:

            # Get the basename:
            image_filename = os.path.basename(image[1])

            # Reconstruct the full image path:
            image_file_path = folder + "attachments/" + image_filename

            # Open the image file:
            with open(image_file_path, "rb") as image_file:
                
                # Encode into Base64:
                image_b64_bytes = base64.b64encode(image_file.read())
                image_b64_string = image_b64_bytes.decode('ascii')

                # Search and replace image paths tith regex:
                b64_image = re.sub(md_img_regex, f"![](data:image/png;base64,{image_b64_string})", note_content)

        print(b64_image)

该代码在下面的代码块中输出 Markdown ,然后在未显示的过程中,我会将其转换为 HTML uysing Python Markdown

您可以看到图像链接确实已被替换为 base64 字符串 - 这样效果很好,但是,每个图像的 base64 字符串都是相同的 - 它是转换循环中最终图像的 base64 字符串。

Lorem Ipsum Dolor Sit Amet

Image 1:
![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAA0ElEQVR4nOyZMQqDQBBFszPbqClshL1N7pDec+UAOZtguUVaIW0is/kjhmTB/zqXj/tY5TNizDmfakL+LbCGQggKISiEoBCCQoj4ejHdJjOUxqRn3b+Z5/7VnRCFEBRCUAhBIQSFEBRCUAgRPaH5PpvrpTmpNPd4qO6EKISgEIJCiLceSmMyQ6Ue2spwHbQzektasYW+8jX4Ae0UblHdI6MQgkKI3wn1l14avF3w/OtYHou5Lq0ECc68NBLUCK9wDWhb+2lPnx34HXLyDAAA//9Z5hvfisgkAQAAAABJRU5ErkJggg==)

Lorem Ipsum Dolor Sit Amet

Image 2:
![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAIAAADYYG7QAAAA0ElEQVR4nOyZMQqDQBBFszPbqClshL1N7pDec+UAOZtguUVaIW0is/kjhmTB/zqXj/tY5TNizDmfakL+LbCGQggKISiEoBCCQoj4ejHdJjOUxqRn3b+Z5/7VnRCFEBRCUAhBIQSFEBRCUAgRPaH5PpvrpTmpNPd4qO6EKISgEIJCiLceSmMyQ6Ue2spwHbQzektasYW+8jX4Ae0UblHdI6MQgkKI3wn1l14avF3w/OtYHou5Lq0ECc68NBLUCK9wDWhb+2lPnx34HXLyDAAA//9Z5hvfisgkAQAAAABJRU5ErkJggg==)

我知道这re.sub显然不是我想象的那样工作,但我不确定如何让它按我想象的方式工作。

我(希望很明显)希望脚本循环的每个图像都替换为其相应的 base64 字符串。

所以,它看起来像下面这样。

Image 1:
![](data:image/png;base64,eiwfjdsfkjwef...

Image 2:
![](data:image/png;base64,43e8hj9igfdk3...

标签: python-3.xbase64

解决方案


文档的第一行re.sub有点偷偷摸摸的 IMO。重点补充:

返回通过替换repl替换字符串中最左边不重叠出现的模式获得的字符串。

这由可选参数专门控制count

可选参数 count 是要替换的模式出现的最大数量;count 必须是非负整数。如果省略或为零,将替换所有匹配项。

现有代码在很多方面显然不正确。根据您希望它的行为方式,它可能正确。您需要有关更大结构的帮助吗?


推荐阅读