前言

  最近整理博客,想要将自己的博文发到其他的博客网站上,如此就遇到了一个问题,如何将md里面嵌套的HTML标签删除。

  因为我的博文都是用Hexo写的,我可以自定义一些按钮来隐藏一些图片,让文章看起来更加简洁。

  但是其他博客网站统统都不支持这种操作,所以我需要想办法用快速的方法将Hexo博文中的HTML标签清除。

  我想到的解决方案就是用正则表达式进行内容替换,这样不需要代码也可以实现批量清理HTML标签。

正则表达式

正则表达式教程

  关于什么是正则表达式,我就不在这里赘述了,需要注意的是正则表达式也分很多种,js比较标新立异,和其他语言不大相同。大多数语言都是相似的。

  我想要实现的是通过Visaul Studio Code里面的搜索替换用正则表达式批量替换文件。

  Visaul Studio Code的替换方式和Visual stuido是相通的。

微软官方的正则表达式的说明

正则表达式效果实现

初步实现效果

  要匹配HTML标签其实非常简单

1
2
3
4
5
6
7
<.*?>
//左匹配尖括号后面内容
//.*批量匹配
//?只匹配一次
//右尖括号结束。
//
//这样所有的<>内容都会被选中

  这里遇到的问题是只能单行适配,而且不能多行识别,比如scirpt标签中的多行内容就无法识别选中

参考链接

  第一个链接的方法纯属扯淡,而重点在于第二链接中的正则表达式

1
2
3
4
5
6
7
8
9
10
11
(<td)( )?(\w*="\w*"( )?){0,9}(>)\r\n.*<cc1:UEditor  

//分析了{0,9}的用法之后
//我自己测了好几遍终于写出了可用的正则表达式

<script>(.*\n){1,}</.*?>

//寻找<script>标签,从这个标签之后开始
//(.*\n)匹配一整行到下一行
//{1,}重复匹配直到结束为止
//</.*?>寻找</的位置,并且使第一次识别完成即结束

  好像已经完美识别了所有HTML标签以及要去除的内容了,然而却遇到了很郁闷的问题,如果我的MD要展示HTML的代码,那么这个部分就不能被替换。

  怎么才能跳过MD中嵌套的部分呢?

进一步的效果实现(错误的思路)

参考链接

  其实这篇文章并没有有用的正则表达式提供给我,不过也算是开拓了我写正则表达式的思路吧。

  后面我是重点看?!和?=的过滤用法,花了很长的时间去想。

1
2
3
4
5
6
7
8
9
(<.*?>)(?=(.*\n){1,}
```html)|(<.*?>)(?!(.*\n){1,}
```)

//最开始我重点研究?!的方法,只实现了后半段
(<.*?>)(?!(.*\n){1,}
```)

//这样可以实现
1
2
3
//然而我却想不到怎么实现保留上面部分
//直到我研究了?=
//这样可以只识别以上的范围,从而过滤
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

(<.*?>)(?=(.*\n){1,}
```html)
//?=可以让前面括号的内容只识别?=后面的内容
//(.*\n){1,}
```html 这个就限定了在
```html 上面的内容
(<.*?>)(?!(.*\n){1,}
```)
//(?!(.*\n){1,}
```)?!就是不识别
```以上的内容给

(<.*?>)(?=(.*\n){1,}
```html)|(<.*?>)(?!(.*\n){1,}
```)
//加入合并识别内容

  最后代码是这样子的

1
2
3
4
5
(<script>(.*\n)+</.*?>)|(<.*?>)(?=(.*\n)+
```[a-zA-Z])|(<.*?>)(?!(.*\n)+
```)
//菜鸟教程里面有提到{1,} 等同于 +(我后面都这样写 比较简洁好看)
//有BUG

  然而经过测试还是有很严重的BUG,只能识别最后一个代码块……

  目前我已经搞到怀疑人生了,猜测可能是VScode不支持这种操作,毕竟它连多行模式都没有。

完美实现

  又经过了一天的思考之后,效果终于实现了,真是非常欣慰,不留遗憾了Y(^o^)Y~~~

  最主要是思路没有想好,就一直在死胡同里面转牛角尖。


  今天研究的时候也有一些失败的例子

1
2
3
4
5
<.*?>|(?=(^
```[a-zA-Z](.*\n)+?^
```))
//这样可以只识别第一个代码块前面的HTML标签
//原理我也不清楚 冏rz

  后面我转换了思路,突然就忽然开朗,既然代码块不能修改,那就选中它,替换的时候保留它就得了。

  感觉自己被?!过滤给坑爹了(:з」∠)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
(^
```(.*\n)+?^
```)|(<script>(.*\n)+?</.*?>)|<.*?>
//完美实现
//VScode 替换的时候输入 $1

(^
```(.*\n)+?^
```)
//识别代码块部分的内容
//^
```表示在首行的
```(避免错误识别了文章中的
```)
//(.*\n)+? 逐行获取内容
//最外面的大括号用于生成$1($1、$2的序号是由括号的顺序生成)

(<script>(.*\n)+?</.*?>)
//参照上文 用于识别<script>代码块

<.*?>
//参照上文 用于识别HTML标签

总结

  为了实现这个效果,最近都弄得茶饭不思,今天终于终于是实现了,不留遗憾的感觉真好~

  通过这次也对正则表达式的使用方法有了深刻的理解,虽然各个语言的正则表达式使用稍有不同,但是还是很好的经验。