Java正则提取SQL文件中SET语句块的问题求助
问题描述
我正在解析一个.sql文件,需要匹配两处多行注释形式的SET语句块:
- 文件开头的SET语句组
- 文件结尾的SET语句组
但我用的正则表达式 ^\/\*![0-9]{0,10}.+?\s.*\*\/;\n^\s*$\n^-- 无法完整匹配,最多只能获取每个目标块的最后两行,试了很多次都没解决。
预期匹配内容
预期匹配1(开头SET块):
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@OLD_SQL_NOTES, SQL_NOTES=0 */;
预期匹配2(结尾SET块):
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
待解析的SQL文件内容:
-- MySQL dump 10.13 Distrib 8.0.32, for Linux (x86_64) -- -- Host: mysql-0 Database: customdb -- ------------------------------------------------------ -- Server version 5.7.39-log /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; /*!40103 SET TIME_ZONE='+00:00' */; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*!40111 SET @OLD_SQL_NOTES=@OLD_SQL_NOTES, SQL_NOTES=0 */; -- -- Dumping data for table `custom_company` -- INSERT IGNORE INTO `custom_company` VALUES ('TESTCOMPANYGMBH','TESTCOMPANY','Test Company',100000001); INSERT IGNORE INTO `version_custom` VALUES ('2022-09-19 04:02:05',NULL,20); INSERT IGNORE INTO `version_custom` VALUES ('2022-09-19 04:02:05',NULL,21); /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -- Dump completed on 2023-03-02 3:18:10
解决方案
问题根源
原正则仅匹配单条SET语句加后续空行和注释,未处理连续的多条SET语句,因此只能捕获最后一行。此外需要开启多行模式,让^和$匹配每行的首尾,而非整个字符串的首尾。
正确正则表达式
匹配开头SET块:
^\/\*![0-9]{4,10} SET.*?\*\/;\s*(?:\n\/\*![0-9]{4,10} SET.*?\*\/;)*
匹配结尾SET块:
^\/\*![0-9]{4,10} SET.*?\*\/;\s*(?:\n\/\*![0-9]{4,10} SET.*?\*\/;)*(?=\n-- Dump completed)
正则解释
^\/\*![0-9]{4,10} SET.*?\*\/;:匹配单条带版本注释的SET语句,.*?采用非贪婪匹配避免跨语句捕获\s*:匹配语句后的空白字符(含换行)(?:\n\/\*![0-9]{4,10} SET.*?\*\/;)*:非捕获组,匹配后续连续的多条SET语句,*表示可匹配0次或多次- 结尾块的
(?=\n-- Dump completed):正向预查,确保匹配的SET块后紧跟Dump完成的注释,精准定位结尾块
使用说明
需确保正则引擎开启多行模式(m flag),例如在Python中使用re.findall(pattern, sql_content, re.M),或在测试工具中勾选Multiline选项。
内容的提问来源于stack exchange,提问作者user3008410
相关产品推荐
相关产品推荐

