Typora 笔记迁移 Obsidian 图片链接转换

news/2025/10/1 14:07:29/文章来源:https://www.cnblogs.com/zqingyang/p/19122408

附件:Typora 笔记迁移 Obsidian 图片链接转换

需求

将typora笔记库迁移到Obsidian,但是typora的图片使用的是严格markdown ![](),Obsidian是wiki ![[]]

笔记库文件夹下面有超级多的.md笔记,手动操作太慢了,因此采用Python进行处理,进行批量修改文章链接格式。

![Pasted image 20221223164738.png](./Database/Pasted image 20221223164738.png)---->![[Pasted image 20221223164738.png]]

由于Obsidian是wiki ![[]] 因此后面采用程序或手动方式,将所有的图片移动到Obsidian仓库下指定图片文件夹即可,例如asset

思路

1、检测该链接是否为图片?![](./Database/
2、正则表达式匹配,![](./Database/任意内容)
3、替换`![](./Database/任意内容)`为`![[任意内容]`---->`![[Pasted image 20221223164738.png]`

实践

备份整个目标文件夹,打压缩拷贝该文件夹副本进行操作。

参考目录

|-- 转换
|   |-- typora_to_obsidian.py
|   `-- 综合软件使用教程 # 目标文件夹
|       |-- Database

安装python,网上教程很多,不再赘述。

  1. 保存脚本: 将下面的代码保存为一个 .py 文件,例如 rename_md.py

  2. 运行脚本: 打开终端或命令行工具,进入你保存脚本的目录,然后运行它:

    typora_to_obsidian.py
    

    程序会提示您输入笔记库的文件夹路径。只需将文件夹的绝对路径复制粘贴进去,然后按回车键即可。
    image

  3. 检查结果: 脚本会自动扫描该文件夹及其所有子文件夹中的 .md 文件,并完成链接的替换。处理过程会显示在终端中。

检查

谨慎一下,要进行检查,打开修改后的任意.md笔记,在typora中进行正则表达式查找:
!\[([^\[\]]*)\]\(([^()]*)(\s+["'].*?["'])?\) 可见,下面没有被替换的均为网络链接格式和示范笔记。

手动将转换成功的.md笔记移动到Obsidian笔记库中的新的位置。
采用程序或手动方式,将所有的图片移动到Obsidian仓库下指定图片文件夹即可,例如asset
打开一篇笔记,可见正常显示。

image

因此,本次转换图片链接操作成功!

image

代码

Python代码

import os
import re
import sysdef convert_image_links(directory):"""遍历指定目录下的所有 Markdown 文件,并将 Typora 格式的图片链接转换为 Obsidian 格式。Typora 格式 1: ![](./some_folder/image.png)Typora 格式 2: ![alt-text](./some_folder/image.png)Obsidian 格式: ![[image.png]]"""# 支持常见的图片文件扩展名image_extensions = ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'svg', 'webp']# 构建正则表达式,用于匹配 Typora 的图片链接# 解释:# !\[.*?\]\(   : 匹配 "![",然后是任意数量的字符 (alt text),然后是 "]("# (?:.*/)?    : 匹配并忽略路径部分 (e.g., "./Database/")。#              (?:...) 是一个非捕获组。#              .* 表示任意字符,/ 是路径分隔符。? 表示路径是可选的。# (.*?)        : 捕获图片文件名 (非贪婪模式)。这是我们需要的核心内容。# \.           : 匹配文件名和扩展名之间的点。# ({})         : 将支持的图片扩展名插入正则表达式。# \)           : 匹配最后的 ")"pattern_str = r'!\[.*?\]\((?:.*/)?(.*?\.({}))\)'.format('|'.join(image_extensions))# 添加 re.IGNORECASE 标志以忽略扩展名的大小写image_pattern = re.compile(pattern_str, re.IGNORECASE)# 遍历指定目录for root, _, files in os.walk(directory):for filename in files:if filename.endswith('.md'):file_path = os.path.join(root, filename)try:with open(file_path, 'r', encoding='utf-8') as f:content = f.read()# 使用正则表达式查找并替换所有匹配的链接# sub 函数的第二个参数 r'![[\1]]' 中的 \1 代表正则表达式中第一个捕获组的内容,# 也就是我们需要的图片文件名 (e.g., "image-20250726104501340.png")new_content, num_replacements = image_pattern.subn(r'![[\1]]', content)if num_replacements > 0:# 如果发生了替换,则将新内容写回文件with open(file_path, 'w', encoding='utf-8') as f:f.write(new_content)print(f"处理文件: {file_path}")print(f"  -> 成功转换 {num_replacements} 个链接。")except Exception as e:print(f"处理文件 {file_path} 时出错: {e}", file=sys.stderr)print("\n所有文件处理完毕!")if __name__ == '__main__':# 提示用户输入要处理的文件夹路径# 在 Windows 上,你可以直接复制文件夹路径,例如: C:\Users\YourName\Documents\MyNotes# 在 macOS 或 Linux 上,路径类似: /Users/YourName/Documents/MyNotestarget_directory = input("请输入您的笔记库文件夹的绝对路径: ")if os.path.isdir(target_directory):convert_image_links(target_directory)else:print("错误: 您输入的不是一个有效的文件夹路径。", file=sys.stderr)

正则表达式代码

!\[([^\[\]]*)\]\(([^()]*)(\s+["'].*?["'])?\)

这个正则表达式 !\[([^\[\]]*)\]\(([^()]*)(\s+["'].*?["'])?\) 是用来精确匹配并提取标准 Markdown 格式的图片链接的各个部分的。

整体结构

这个表达式匹配的完整格式是: ![alt text](image_path "optional title")

它被分成了几个主要部分来分别捕获 alt text (替代文本)、 image_path (图片路径) 和 optional title (可选的标题)。

各部分详解

正则表达式部分 含义解释
! 匹配一个字面量的感叹号 !,这是 Markdown 图片语法的起始标志。
\[ 匹配一个字面量的左方括号 [。因为 [ 是元字符,所以需要用 \ 来转义。
([^\[\]]*) 第一个捕获组 (Group 1): • (...):定义一个捕获组,用于提取括号内的匹配内容。 • [...]:定义一个字符集。 • ^:在字符集 [] 内部表示“非”,即匹配任何不包含在后面的字符。 • \[\]:这里指的是 [] 这两个字符。 • *:表示匹配前面的字符集零次或多次。 作用:捕获方括号 [] 之间的所有内容,即图片的 替代文本 (alt text)
\] 匹配一个字面量的右方括号 ]
\( 匹配一个字面量的左圆括号 (
([^()]*) 第二个捕获组 (Group 2): • (...):定义捕获组。 • [^()]:匹配任何不是 (不是 ) 的字符。 • *:匹配零次或多次。 作用:捕获圆括号 () 之间的内容,即图片的 路径或URL (image_path)
(\s+["'].*?["'])? 第三个捕获组 (Group 3),且为可选部分: • (...):定义捕获组。 • ?:表示整个第三个捕获组是可选的(可以出现0次或1次)。 • \s+:匹配一个或多个空白字符(如空格)。 • ["']:匹配一个双引号 " 或一个单引号 '。 • .*?:非贪婪匹配。匹配任意字符 (.) 零次或多次 (*),但尽可能少地匹配 (?),直到遇到下一个模式。 • ["']:匹配一个结束的双引号 " 或单引号 '作用:捕获可选的图片标题 (title),它由空格和引号包围。
\) 匹配一个字面量的右圆括号 )

总结

  • !\[ ... \]: 匹配 ![alt text] 的框架。
  • (...): 括号内的部分是捕获组,意味着在查找替换时,你可以用 $1, $2, $3 (或 \1, \2, \3,取决于具体工具) 来引用这些捕获到的内容。
    • $1 对应 ([^\[\]]*),即图片的替代文本。
    • $2 对应 ([^()]*),即图片的路径。
    • $3 对应 (\s+["'].*?["'])?,即可选的、带引号的标题。

这个正则表达式可以准确地处理包含或不包含可选标题的各类标准 Markdown 图片链接,同时避免错误匹配嵌套的括号或格式不规范的文本。

注意事项

  1. 备份: 强烈建议在运行此脚本前,先备份你的整个文件夹。 文件重命名是一个不可逆的操作,以防万一出现非预期的结果。

参考

  1. [wiki链接和markdown链接 对比 互相转换](https://garden.czchx.cc/czc知识库/笔记/知识库搭建/1-obsidian笔记/子/wiki链接和markdown链接 对比 互相转换/)
  2. PKMer_Wiki 链接和 markdown 链接之间的转换
  3. 一文搞懂正则表达式 - 知乎

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/923915.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Java八股文】12-分布式面试篇 - 教程

【Java八股文】12-分布式面试篇 - 教程pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mon…

Java 运行 Word 文档标签并赋值:从基础到实战

Java 运行 Word 文档标签并赋值:从基础到实战pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &q…

上海配资网站开发广州开发区投资集团有限公司

都是copy的百度SDK文档,简单说说怎么用。1、没安装Python的参见此文:Python学习笔记系列 1 ——安装调试Python开发软件2、winr输入cmd打开命令行,输入:pip install baidu-aip,如下安装百度AI的模块。3、新建文本文档&…

词云组件

效果图: 组件代码:<template><div class="post"><div class="portal-title flex-h justify-between"><div class="flex-h"><img class="icon"…

域名 网站名称网站建设对电子商务的作用

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

网站制作的关键技术新乡手机网站建设电话

文章目录 一、JavaScript 逻辑运算符1、逻辑运算符 概念2、逻辑与运算符 &&3、逻辑或运算符 ||4、逻辑非运算符 !5、完整代码示例 一、JavaScript 逻辑运算符 1、逻辑运算符 概念 JavaScript 中的 逻辑运算符 的作用是 对 布尔值 进行运算 , 运算完成 后 的 返回值 也是…

没有网站也可以做外贸吗wordpress和万网

碰撞 Collision. [kəˈliʒən] 碰撞&#xff1b;冲突&#xff1b;&#xff08;意见&#xff0c;看法&#xff09;的抵触&#xff1b;&#xff08;政党等的&#xff09;倾轧 选择一个需要添加碰撞器的游戏对象后 Component->Physics- Unity一共为对象提供了6 种碰撞器&…

监控设备网站制作工作服厂家联系方式

目录 1. 更换yum源更新系统软件包&#xff1a; 1.1备份yum源 1.1.1创建备份目录&#xff1a; 1.1.2移动现有仓库配置文件到备份目录&#xff1a; 1.1.3验证备份&#xff1a; 1.2更换yum源 1.2.1添加yum源 1.2.2删除和建立yum缓存 1.3更新系统软件包 1.4 yum与dnf介绍…

2025 年超声波清洗机品牌最新权威推荐排行榜:龙门式 / 悬挂式 / 全自动等多类型设备厂家 TOP3 精选,助力企业精准选购

当前电子、机械、医疗、汽车、新能源等精密制造行业飞速发展,对零部件清洗的精度、效率及环保标准提出更高要求,超声波清洗机作为核心清洗设备,市场需求持续攀升。但市场上品牌繁杂,产品质量、技术水平与服务能力差…

树的统一迭代法

树的统一迭代法是一种比较通用的遍历方法,通过标记法来实现前序、中序、后序遍历,核心思想是通过栈中加入空指针来标记访问节点和处理节点的时机 树的递归遍历 递归遍历比较简单,只要完成模板,更改添加元素的位置代…

怎么seo网站排名wordpress搭建电影

1、自己准备训练语料文件 根据自己的业务场景准备训练数据&#xff0c;比如用户在商城上的同购行为序列或同浏览行为序列。 我们希望通过自己训练业务相关的语料word2vec模型来获得词嵌入、词相关性查询等。 1.1 准备语料库文件 # 示例&#xff1a;准备自己的一个大规模的语…

集团网站开发费用关键词优化的价格查询

1. 题目 给你一个 n 行 m 列的二维网格 grid 和一个整数 k。你需要将 grid 迁移 k 次。 每次「迁移」操作将会引发下述活动&#xff1a; 位于 grid[i][j] 的元素将会移动到 grid[i][j 1]。 位于 grid[i][m - 1] 的元素将会移动到 grid[i 1][0]。 位于 grid[n - 1][m - 1] …

asp网站源码+access+机械移动网站开发技术有哪些

实验项目&#xff1a;RSA公钥加密与签名实验 1.实验目的 本实验的学习目标是让学生获得 RSA 算法的动手经验。 通过课堂学习&#xff0c;学生应该已经了解 RSA 算法的理论部分&#xff0c; 知道在数学上如何生成公钥、私钥以及如何执行加密、解密和签名生成、验证。 通过使用…

深入解析:4-6〔O҉S҉C҉P҉ ◈ 研记〕❘ WEB应用攻击▸文件上传漏洞-A

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025 年冷却塔品牌最新推荐排行榜:玻璃钢冷却塔、闭式冷却塔、方型逆流式冷却塔优质厂家 TOP3 精选,赋能企业选购

随着工业生产与建筑行业的快速发展,冷却塔作为关键散热设备,市场需求日益攀升。但当前市场上冷却塔品牌数量众多,产品质量与性能参差不齐,从散热效率到节能效果,从材质耐用性到售后服务,差异显著。许多企业在选购…

详细介绍:基于Chrome140的FB账号自动化——脚本撰写(二)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

CentOS7二进制安装包方式部署K8S集群之CA根证书生成 - 实践

CentOS7二进制安装包方式部署K8S集群之CA根证书生成 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consol…

网站地址栏做1个响应式设计网站好

全世界只有3.14 % 的人关注了爆炸吧知如何才能学好数学&#xff1f;我国著名数学家苏步青先生曾说&#xff1a;"要学好数学&#xff0c;方法不外乎打好基础&#xff0c;多做习题&#xff0c;多加思索和分析”。为了帮助大家学好数学&#xff0c;今天&#xff0c;超模君要给…

旅游网站开发系统的er图网站建设 公司 广州

1.android电池充满电剩余时间 android电量还需多长时间充满时间计算参考下面链接: [Android Framework] 8.1 Battery系列(四) 电量还需多长时间充满时间计算_batteryinfo.java-CSDN博客 从这个链接中可以看出android默认的计算方式为平均计算每1%所需要的时间,在乘以剩余的电…

旅游景区网站源码长沙网络科技有限公司有哪些

介绍 赋值运算符就是将某个运算后的值&#xff0c; 赋给指定的变量。 赋值运算符的分类 基本赋值运算符 例如&#xff1a; int a 10; 复合赋值运算符 &#xff0c; - &#xff0c; * &#xff0c; / &#xff0c; % 等 a b; [等价 a a b; ] a - b; [等价 a a - b; ] …