RegEx用于多行搜索并替换为SQL查询代码

问题描述

Internet上有很多有关“使用正则表达式搜索和替换”主题的合格文档。他们中只有少数几个展示了如何在多行上下文中执行此操作。更少的节目表明如何为其中的几个项目生成正则表达式。

我已经在编辑器(EditPad Pro,RJ TextED,EmEditor,Notepad ++,Sublime Text 3,Visual Studio Professional 2019,最新的JetBrains PHPstorm版本以及其他)中尝试了可安装的RegEx工具和在线RegEx服务(正则表达式101, RegExr),全天阅读与我的标题标准相对应的StackOverflow答案,并尝试充分利用各种在线教程。

您称我为愚蠢,但我无法理解以下概念是否完全可行

我要更改的SQL查询部分如下:

    AND op.OP1OPVerfahren > 0

    AND p.Testzwecke = 0

    AND NOT EXISTS (SELECT disTINCT 1 FROM ods39.dat_optherapie op2 WHERE op2.patID = p.ID AND op2.revision > op.revision)

    UNION ALL

传奇:

  • op.OP1OPVerfahren是第一个执行的手术的数据库字段,可以记录10个手术程序(OP1OPVerfahrenOP10OPVerfahren
  • p.Testzwecke是对患者个人数据(例如名字,姓氏等)的联接。
  • ods39.dat_optherapie数据库dat_optherapie中的表ods39-系统由50个结构完全相同的MysqL数据库组成
  • p.ID仅仅是患者的ID
  • op.revision一个自动递增的跟踪器,用于保存相同手术步骤的数据记录集的数量(有时需要进行精确度的修订)

查询的上述部分具有相关的定量复杂性:在查询中,此细分在以下变体中出现780次:

    AND **op.OP1OPVerfahren** _up_to_ **op.OP10OPVerfahren** > 0

    AND p.Testzwecke = 0

    AND NOT EXISTS (SELECT disTINCT 1 FROM **ods01.dat_optherapie** _up_to_ **ods39.dat_optherapie** op2 WHERE op2.patID = p.ID AND op2.revision > op.revision)

    UNION ALL

要完全理解我要在此处解决的问题,我想将上述提到的内容替换为:

    AND **op.OP1OPVerfahren** _up_to_ **op.OP10OPVerfahren** > 0

    AND p.Testzwecke = 0

    AND NOT EXISTS (SELECT disTINCT 1 FROM **ods01.dat_optherapie** _up_to_ **ods39.dat_optherapie** op2 WHERE op2.patID = p.ID AND op2.revision > op.revision)

    GROUP BY **OP1OPVerfahren** _up_to_ **OP10OPVerfahren**

    UNION ALL

第一行的op.OP_x_OPVerfahren x = 1到10)和OP_x_OPVerfahren x = 1到10) GROUP BY语句在数值上相互关联,即e。当我想将我的替换程序从op.OP1OPVerfahren的39个数据库更改为op.OP2OPVerfahren的39个数据库,依此类推时,GROUP BY号将相应更改。

现在,将对所有39个数据库进行此替换。整个SQL查询代码大约是20.000行代码,这是我不想在手动替换上花费数小时的原因,因为在不同文件中还有更多此类SQL查询结构需要以相似的方式进行替换。

举个例子:

代码...

    AND op.OP1OPVerfahren > 0

    AND p.Testzwecke = 0

    AND NOT EXISTS (SELECT disTINCT 1 FROM ods39.dat_optherapie op2 WHERE op2.patID = p.ID AND op2.revision > op.revision)

    UNION ALL

...对于39个数据库GROUP BY OP1OPVerfahren,需要在UNION ALL之前的ods01之前扩展为ods39。然后再次使用op.OP2OPVerfahrenOP2OPVerfahren来访问相同的39个数据库,直到最终达到(op.)OP10OPVerfahren(= 780个替换)。

新插入的GROUP BY语句的OP_x_...计数应与op.OP_x_...编号相同。

根据上述编辑者的个人需要,我尝试了很多不同的正则表达式语句(例如\ d \ d,(\ d)(\ d),\ d {2}等)使用),但我无法根据数据库op.OP_x_OPVerfahren的“号码检测”来找出如何进行一个“号码检测”(OP_x_OPVerfahrenods_x_.dat_optherapie)。>

非常感谢您从最宝贵的经验和专业知识中获得的帮助,也非常感谢您收到除了具有良好(甚至可测试)正则表达式处理能力的上述编辑以外的其他建议。

解决方法

我们可以使用正则表达式替换来完成这项工作:

(AND\ +op\.(OP\d0?OPVerfahren)\ *>\ *0\s+AND\ +p\.Testzwecke\ *=\ *0\s+AND\ +NOT\ +EXISTS\ *\(SELECT\ +DISTINCT\ +1\ +FROM\ +ods[0123][0-9]\.dat_optherapie\ +op2\ +WHERE\ +op2\.patID\ *=\ *p\.ID\ +AND\ +op2\.revision\ *>\ *op\.revision\))(\s+UNION\s+ALL)

Demo

它与原始字符串相当紧,并且大多数情况下仅引入了空白字符的变长量词。如果存在\ *,则使用可选的\ +时,可能会出现一个可选的空格。否则,空白速记字符\s用于不仅允许空格,而且还允许换行符等。要使其起作用,请启用s | singleline标志(或在模式前面添加(?s))。

,

我相信类似以下正则表达式查找/替换表达式的内容将满足您的要求:

查找:

AND op.OP(\d{1,2})(OPVerfahren.*?\))

替换为:

AND op.OP$1$2 \n GROUP BY OP$1OPVerfahren

请注意,它需要为正则表达式设置“全局”和“点匹配换行符”选项。

为简单说明,它有2个捕获组,一个捕获op.OP和OPVerfahren之间的数字,第二个捕获组捕获到此之后的所有内容,直到“(SELECT DISTINCT ...)”的右括号为止。然后在正则表达式的替换部分中将它们分别用作$ 1和$ 2。

测试示例here。我相信这应该可以在Notepad ++中使用。

(顺便说一句,我认为您的“ GROUP BY OP1Verfahren ”应该是“ GROUP BY OP1OPVerfahren ”对吗?即2个“ OP”!)