[Markdown] 使用正则表达式处理 Markdown 文档的个人用例

1,214 阅读3分钟

正则表达式

1.Markdown 标题目录相关

1.标题加粗

需求:我有很多以 1. 2. 开头的小标题,他们不是用 # 号标识的标题,但是我需要给他们加粗以分级

思路:使用 (^[1-9]\.[^\s][\s\S][^()()::]*$) 查找,**$1** 替换

在开头使用 [^\s] 是为了排除排序列表 1.空格 2.空格的干扰

在结尾使用 [^()()::] 是因为例题也是以 1. 2. 开头,但是以 (): 结尾,要排除例题的干扰

2.目录换行

需求:Markdown All in One 插件生成的目录的项之间是没有换行的,这看上去就很不舒服,我觉得需要加上换行

思路:使用 (^[\s]*-[\s\S]*$) 查找,$1\n 替换

但是这样会导致查找到用于分段的 ---

于是改为 (^[\s]*-[\s\S]*\)$),要求末尾有个 )

3.标题去掉数字标号

需求:使用 VS Code 的 Markdown Preview Enhanced 插件,使用了标题自动编号的 css,因此原来 markdown 文档里面已经带了数字编号的标题应该把数字编号去掉

之前:#### 1.2.3 永真、永假、可满足

之后:#### 永真、永假、可满足

思路:使用 #[\s][\S]*[\s]([\u4e00-\u9fa5]) 查找,# $1 替换

2.Markdown 表格相关

1.table 居中

需求:用某些工具网站复制粘贴 excel 转换得到的 markdown table 是没有居中的

需要把 |---| 替换为 |:---:|

思路:用 \|[\-]+ 查找,用 |:---: 替换

只查 |---| 的前缀,是因为如果查找到的字符串包括两个 | 号,那么就会出现两个 |---| 中间的部分没有查找到的情况。原因在于包括两个 | 号的字符串抢走了潜在目标字符串的前缀中的 |

2.table 栏清除重复空格

需求:用某些工具网站复制粘贴 excel 转换得到的 markdown table 栏经常包含多余空格,需要去掉重复的

思路:

\|[\s]+ 查找,|空格 替换,可以去掉内容前面的重复空格

[\s]+\| 查找,空格| 替换,可以去掉内容后面的重复空格

3.排版相关

1.去掉结尾的全角冒号句号并换行

需求:给定的文档在列表时,每一项之间没有换行,还都以全角冒号或者句号结尾,紧紧挨在一起真的很不舒服

思路:使用 [:。]$ 查找,使用 \n 替换

4.Markdown 公式相关

1.替换 markdown 公式的开头和结尾内紧接着的空格

需求:

类似 $ f(x) $ 的表达式,在 VS Code 中是可以预览出公式的,但是在 Obsidian 中预览不出

试验之后发现必须要 $f(x)$ 才行

因此要将 markdown 中公式的开头符号 $ 后面紧跟着的若干空格删去,将结尾符号 $ 前面紧接着的若干空格删去

思路:

1)使用 \$\s[^\$]*\s\$ 可以找到以 $空格 开头,且以第一个 空格$ 结尾的字符串

\$$ 的转义

\s 是空白字符

[^abc] 匹配除了 a, b, c 以外的任意字符

* 前面的字符重复零次或更多次

不使用 ^ 或者 $ 来定位,因为它们定位的是一个行的开始和结尾

问题:可能不会匹配到正确的公式

match_space_1.png

错误原因在于实际文档中可能存在以 $空格 开头,且以第一个 空格$ 结尾的公式,也可能存在以 $ 开头,中间没有空格,且以第一个 $ 结尾的公式

2)使用 \$[\s]*[^\$]*[\s]*\$ 可以找到以 $若干空格 开头,且以第一个 若干空格$ 结尾的字符串

使用 \$[\s]*([^\$]*)[\s]*\$ 更进一步使用 () 保存找到的部分字符串

replace 栏中 $1 表示找到的第一个部分字符串,$ 表示转义

使用 $$$1$ 替换

问题:可能无法替换开头结尾紧跟着的空格

match_space_2.png

错误原因在于开头结尾紧跟着的空格被 [^\$] 匹配进去了

3)使用 \$[\s]*([^\$\s][^\$]*[^\$\s])[\s]*\$ 寻找以 $若干空格 开头,中间部分开头字符和结尾字符非空,且以第一个 若干空格$ 结尾的字符串

同理用 $$$1$ 替换

2.Markdown 公式的前后添加空格

需求:别人的文档里面公式与中文是紧挨着的

个人觉得在非中文符号与中文之间添加空格是比较符合规范的,也是更好看的

思路:

使用 \$([\u4e00-\u9fa5]) 查找一次,用 $$ $1 替换

使用 ([\u4e00-\u9fa5])\$ 查找一次,用 $1 $ 替换

其中,[\u4e00-\u9fa5] 表示中文字符

3.删除数字和字母为主要部分的 Markdown 公式的公式符号

需求:如题

我是不太理解为什么这都要加个公式符号,看上去很杂乱诶……

思路:使用 \$([A-Za-z\/\-\+\*","\.\s\(\)">"]+)\$ 查找一次,用 $1 替换

其中,逗号的转义是 "," 而不是 \,

特别地,不匹配 \,因为它可能用于 latex 公式中的转义

匹配 - > () 是为了匹配 M(MAR) -> MDR 这类的公式

使用 \$([0-9\/\-\+\*","\.\s\(\)">"]+)\$ 查找一次,用 $1 替换

同理,不匹配 \

不使用 \$([A-Za-z0-9\/\-\+\*","\.\s\(\)">"]+)\$ 的原因是文档里有一些数字加单位的公式

这些公式里的单位有的是纯字母,有的是希腊字母,情况还有点复杂