# 使用正则表达式进行高级替换

> 发布于：2022-06-17 | 分类：技能分享, 笔记 | 原文：https://www.imbailey.cn/post/advanced-regex-replacement

## 需求

最近跟正则表达式杠上了。有这样一个需求，我的博客文章是用typora写的，markdown格式的语法插入图片的表达是这样的：

```python
![](https://myblog-1257298572.cos.ap-shanghai.myqcloud.com/img/IMG_1562%20%E5%A4%A7.jpeg)
```

但是这样渲染出的图片不能居中，也不能缩放，我得把它转换成博客主题的格式：

```python
\{\{< figure src="https://myblog-1257298572.cos.ap-shanghai.myqcloud.com/img/IMG_1562%20%E5%A4%A7.jpeg" >\}\}（为了防止渲染原文没有\斜杠）
```

思路很简单，但不能简单的使用python的`replace`函数，因为不仅要匹配`![]()`，还要匹配括号里的url

## 代码

可以拿这个网站试一试：https://regex101.com

点左边`FUNCTION`里的`Substitution`，就是替换模式

`TOOLS`里的`Code Generator`可以生成代码（不过python的代码不太好用）

```python
# 匹配字符串
r"!\[.*\]\((https:\/\/myblog.*)\)"
```

```python
# 替换字符串
'/{/{< figure src="\\1" >/}/}'（为了防止渲染原文没有/斜杠）
```

这里面的`\\1`就表示匹配字符串里用括号包围起来的那部分，replace是没有这种功能的。

完整代码：

```python
import os
import re
path = "" # 文件夹路径
file = "" # 文件名

with open(os.path.join(path, file),"r") as f:
    all_text = f.read()
    res = re.sub(r"!\[.*\]\((https:\/\/myblog.*)\)", '/{/{< figure src="\\1" >/}/}', all_text, 0, re.MULTILINE) # （为了防止渲染原文没有/斜杠）
    
    
with open(os.path.join(path, file),"w") as f:
    f.write(res)
```

## re.sub

```python
def sub(pattern, repl, string, count=0, flags=0):
    """Return the string obtained by replacing the leftmost
    non-overlapping occurrences of the pattern in string by the
    replacement repl.  repl can be either a string or a callable;
    if a string, backslash escapes in it are processed.  If it is
    a callable, it's passed the match object and must return
    a replacement string to be used."""
    return _compile(pattern, flags).sub(repl, string, count)
```
1）pattern：该参数表示正则中的模式字符串；
（2）repl：该参数表示要替换的字符串（即匹配到pattern后替换为repl），也可以是个函数；
（3）string：该参数表示要被处理（查找替换）的原始字符串；
（4）count：可选参数，表示是要替换的最大次数，而且必须是非负整数，该参数默认为0，即所有的匹配都会被替换；
（5）flags：可选参数，表示编译时用的匹配模式（如忽略大小写、多行模式等），数字形式，默认为0。

`re.MULTILINE`:多行模式
