正则表达式写法,批量替换数据库字符串

nZone 2023年10月23日更新于1 年前 共1578字 57行代码 预计8分钟 评论 80

偶然间发现这篇文章的图片不会显示,查看代码发现是媒体库路径的问题,我的路径是不固定的,不同主题的文章是上传到不同的目录,媒体库图片ID是固定的。

如果我后台改上传路径,就可能导致有的文章图片在前台无法显示。虽然图片也有绝对地址,但前台还是会用媒体库的路径显示。

正则表达式写法

实例要把较为复杂的整段代码替换,试用很多插件,也是运行不了,可能数据库版本不支持,不过关键还是正则表达式要写对。正则表达式语法可参考 Notepad3 的说明。

<!-- wp:image {"align":"center","id":1946,"sizeSlug":"full","linkDestination":"none"} -->
<figure class="wp-block-image aligncenter size-full"><img src="https://www.nzonex.com/file/pic/qq/qie3.jpg" alt="微视无法解除更换授权" class="wp-image-1946"/></figure>
<!-- /wp:image -->

想要把第一行的媒体库ID和居中的相关参数删掉,考虑参数不统一,还有点复杂,还容易出错,把目标直接改成查找整行,如果置空系统会自动加,所以替换为:

<!-- wp:image {"sizeSlug":"large"} -->

第一行正则表达式如下:

<!-- wp:image {.*?} -->

这个正则表达式会匹配以 <!-- wp:image { 开头,} --> 结尾的字符串,中间可以包含任何字符,.*?表示非贪婪匹配,以匹配最短的内容,如果没有?则是贪婪匹配,会匹配更多内容,测试会多选好几行。

Notepad3的正则表达式语法

另外要把后面的媒体库ID参数删掉,这数字是不固定的:

 class="wp-image-1946"

为避免出错,用替换的方式,把后面的几个字符也加进来,也就是把:

/*无反斜杆*/
 class="wp-image-1946"/></figure>
/*有的有反斜杆*/
 class=\"wp-image-2848\"/></figure>

替换为(class前面是还有个空格,强迫症有影响)

/></figure>

这个正则表达式就有点复杂了,其实不难,但我用人工智能都写不对,正确的是:

/*无反斜杆*/
 class="wp-image-\d+"/></figure>
/*有反斜杆*/
 class=\\"wp-image-\d+\\"/></figure>

有单斜杆\要转义成两个斜杆\\,单个十进制数字是用\d表示,加个+表示任意数字。

数据库正则表达式写法

用正则匹配时,最好导出数据库搜索测试一下,直接在数据库执行SQL代码风险非常大,毕竟不是文本搜索替换。但我用正则去替换提示0,不支持这个写法。

UPDATE wp_posts
SET post_content = REGEXP_REPLACE(post_content, '<!-- wp:image {.*?} -->', '<!-- wp:image {"sizeSlug":"large"} -->');
测试正则表达式是否正确
UPDATE wp_posts
SET post_content = REGEXP_REPLACE(post_content, ' class=\\"wp-image-\d+\\"/></figure>', '/></figure>');
UPDATE wp_posts
SET post_content = REGEXP_REPLACE(post_content, ' class="wp-image-\d+"/></figure>', '/></figure>');

要注意的是,MySQL 在版本 8.0.23 和更新版本中才引入了 REGEXP_REPLACE 函数。如果 MySQL 版本比较低,这个查询将不起作用。低版本可以参考用以下方法:

UPDATE wp_posts
SET post_content = CONCAT(
    SUBSTRING_INDEX(post_content, '<!-- wp:image {', 1),
    '<!-- wp:image {"sizeSlug":"large"} -->',
    SUBSTRING(post_content, LOCATE('}', post_content) + 1)
)
WHERE post_content REGEXP '<!-- wp:image {[^}]+} -->';

图片 size-full 和 size-large的区别

发现保存文章后,会自动改代码。应该是受到关联代码影响,这个图片块使用了 size-full 的类名,图片显示大小为全尺寸,即以其原始大小显示, aligncenter 是对齐方式为居中。

<figure class="wp-block-image aligncenter size-full">

要把图片块改成使用 size-large 类名,这尺寸是由主题或插件定义,同时删掉 aligncenter ,根据默认规则进行对齐:

<figure class="wp-block-image size-large">

最后发现我只要改掉第二行,第一行就自动修改了,前提是第一行要先清空状态,不然第一行有参数单独改第二行也没用。最后干脆把所有参数都清空了,做法是:先清空第一行,再清空第二行。

<!-- wp:image -->
<figure class="wp-block-image">

批量替换数据库字符串

因为用 phpmyadmin 操作 MySQL 提示错误:#1139 - Got error 'repetition-operator operand invalid' from regexp,想到还是用帝国备份王吧,备份数据库后直接用文本替换。

不过帝国自带的替换操作也是不好用,提示成功但实际没替换,可能备份的数据库文件有转义,所以正则表达式也就不能通用了。

帝国备份王

帝国备份参数,建议调整每组备份大小,我是直接加个0,太小分卷太多影响效率,数据存放格式改为正常,这样才能编辑,导入方式默认就是 replace,勾选完整插入,底下只勾选“wp_posts”即可,这样操作精准,备份恢复都比较快。

考虑本文篇幅太长了,所以把要替换的都全部放一起了,都是正则表达式。

<!-- wp:image {.*?} -->
<!-- wp:image -->

/*下面3个都替换为第4个*/
 class=\\"wp-image-\d+\\"/></figure>
 class="wp-image-\d+"/></figure>
 class=\\"wp-image-.*?/></figure>

/></figure>

wp-block-image .*?\\
wp-block-image\

用这种方式操作,比直接操作数据库更安全,因为比较直观,可以一个个替换,或者全部替换。

之前用 Notepad3 和 Notepad++ 编辑保存都无法恢复,后面用 Notepad2 居然可以。

折腾了一天,其实这可能是主题问题,我却想直接去修改数据库里的文章代码,文章数量不多,删除一点代码并不会减少多少体积。因为数据恢复不是最新的,网站相当于断片了几个小时。

weinxin
公众号
闹着玩下网
avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: