新尝试单独开一贴。
MDX的修订,现在大多还是手工+正则的形式一条条替换,此贴尝试用 patch文本的形式解决批量替换的问题。
以下面这个 MDX 原始文本为例:
down
<span>Get down off the taable.</span>
</>
float
<span>I wasn’t sure if the raft would float.</span>
</>
上面的 taable 需要替换成 table,另外我们加个需求,所有 span 外加上div 标签,这里使用正则。
Patch文本的组织形式和 mdx 文本保持一致,用</>分开需要修的词头,第一行需要匹配的词头, 第二行是需要修的文本,第三行是替换文本, patch文本的格式:
down
the taable
the table
</>
*
(<span>(([\s\S])*?)<\/span>)
<div>$1</div>
</>
上面比较特殊的是,有个星号(*)在第一行,这表示所有词头里替换,第二,三行用正则替换,完成span 外套 div。整个 patch 文本,按顺序执行。这些都可以手工修,问题是很繁琐,文本 patch的形式,会更清楚些,也方便分享,替换结果:
down
<div><span>Get down off the table.</span></div>
</>
float
<div><span>I wasn’t sure if the raft would float.</span></div>
</>
衍生处理,还可以替换词头,拆分词头之类的,实现的Python2脚本:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import re
def read_text(path):
with open(path, "r") as f:
text = f.read()
return text
# run: python patch.py mdx.txt patch.txt
def main(argv):
if len(sys.argv) != 3:
sys.ext(2)
mdx = read_text(sys.argv[1])
items = []
for item in [x.strip() for x in mdx.split("</>") if x.strip()]:
i = item.find("\n")
if i != -1:
word = item[0: i].strip()
content = item[i:].strip()
items.append((word, content))
rules = []
for patch in read_text(sys.argv[2]).split("</>"):
arr = patch.splitlines();
arr[:] = [x.strip() for x in arr if x.strip()]
if len(arr) == 3:
rules.append((arr[0], arr[1], arr[2]))
for rule in rules:
match, r1, r2 = rule[0], rule[1], rule[2]
r2 = r2.replace('$', '\\')
for i, item in enumerate(items):
word, content = item;
if match == '*' or match == word:
content = re.sub(r1, r2, content)
items[i] = (word, content)
with open("mdx_new.txt", "a") as f:
for item in items:
word, content = item
f.write(word.strip())
f.write("\n")
f.write(content.strip())
f.write("\n")
f.write("</>\n")
if __name__ == "__main__":
main(sys.argv[1:])
可以下载尝试,patch.zip (2.5 KB),包含 patch.py, mdx.txt, patch.txt 。
python patch.py mdx.txt patch.txt
会生成修订好的 mdx_new.txt