使用 RegEx 解析 Transact SQL

Vec*_*tor 3 regex t-sql parsing text

我对正则表达式缺乏经验 - 只是偶尔使用简单的正则表达式来完成我通过反复试验得出的编程任务,但现在我面临着严重的正则表达式挑战:

我有大约 970 个包含 Sybase Transact SQL 片段的文本文件,我需要找到这些文件中的每个表名,并在表名前面加上“#”。因此,我的选择是要么花一周时间手动编辑文件,要么使用 regEx(Python 3 或 Delphi-PRCE)编写脚本或应用程序来执行此任务。

规则如下:

表名始终是大写的 - 所以我只寻找大写的单词;

列名、SQL 表达式和变量始终为小写;

SQL 关键字、表别名和列值可以大写,但不能以“#”为前缀;

表别名(不得加前缀)前面始终有空格,直到前一个单词(这将是表名称)的末尾。

列值(不得加前缀)可以是数值,也可以是用引号引起来的字符。

以下是一些需要应用上述所有规则的示例文本:

update SYBASE_TABLE
set ok = convert(char(10),MB.limit)
from MOVE_BOOKS MB, PEOPLEPLACES PPL
where MB.move_num = PPL.move_num
AND PPL.mot_ind = 'B'
AND PPL.trade_type_ind = 'P'
Run Code Online (Sandbox Code Playgroud)

到目前为止,我只做到了这一点:(不算太远......)

(?-i)[[:上:]]

非常感激任何的帮助。TIA,

明尼苏达州

Bar*_*ers 5

这不能通过简单的正则表达式替换来实现。您将无法区分大写单词是表、字符串文字还是注释:

update TABLE set x='NOT_A_TABLE' where y='NOT TABLES EITHER' 
-- AND NO TABLES HERE AS WELL
Run Code Online (Sandbox Code Playgroud)

编辑

您似乎认为确定一个单词是否在字符串文字中很容易,然后考虑这样的 SQL:

-- a quote: '
update TABLE set x=42 where y=666
-- another quote: '
Run Code Online (Sandbox Code Playgroud)

或者

update TABLE set x='not '' A '''' table' where y=666 
Run Code Online (Sandbox Code Playgroud)

编辑二

好吧,我(着迷地)强调了这样一个事实:简单的正则表达式替换是不可行的。但我还没有提供(可能的)解决方案。您可以做的是基于几个不同的正则表达式创建某种“混合词法分析器”。您要做的就是扫描输入文件,并在每个字符的开头尝试匹配 a comment、 a string literal、 akeyword或 a capitalized word。如果前面的 4 个模式都不匹配,则仅消耗单个字符并重复该过程。

Python 中的一个小演示:

update TABLE set x='NOT_A_TABLE' where y='NOT TABLES EITHER' 
-- AND NO TABLES HERE AS WELL
Run Code Online (Sandbox Code Playgroud)

其产生:

UPDATE #SYBASE_TABLE
SET ok = convert(char(10),#MB.limit) -- ignore me!
from #MOVE_BOOKS #MB, #PEOPLEPLACES #PPL
where #MB.move_num = #PPL.move_num
-- comment '
AND #PPL.mot_ind = 'B '' X'
-- another comment '
AND #PPL.trade_type_ind = 'P -- not a comment'
Run Code Online (Sandbox Code Playgroud)

这可能不是您想要的确切输出,但我希望该脚本足够简单,以便您根据需要进行调整。

祝你好运。