gpt4 book ai didi

regex - 使用 RegEx 解析 Transact SQL

转载 作者:行者123 更新时间:2023-12-01 13:00:41 26 4
gpt4 key购买 nike

我对 RegEx 非常缺乏经验 - 只是偶尔为我通过反复试验制定的编程任务直接使用 RegEx,但现在我遇到了一个严重的 regEx 挑战:

我有大约 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'

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

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

任何帮助将不胜感激。TIA,

最佳答案

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

update TABLE set x='NOT_A_TABLE' where y='NOT TABLES EITHER' 
-- AND NO TABLES HERE AS WELL

编辑

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

-- a quote: '
update TABLE set x=42 where y=666
-- another quote: '

update TABLE set x='not '' A '''' table' where y=666 

编辑二

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

Python 中的一个小演示:

#!/usr/bin/env python
import re

input = """
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'
"""

regex = r"""(?xs) # x = enable inline comments, s = enable DOT-ALL
(--[^\r\n]*) # [1] comments
| # OR
('(?:''|[^\r\n'])*') # [2] string literal
| # OR
(\b(?:AND|UPDATE|SET)\b) # [3] keywords
| # OR
([A-Z][A-Z_]*) # [4] capitalized word
| # OR
. # [5] fall through: matches any char
"""

output = ''

for m in re.finditer(regex, input):
# append a `#` if group(4) matched
if m.group(4): output += '#'
# append the matched text (any of the groups!)
output += m.group()

# print the adjusted SQL
print output

产生:

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'

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

祝你好运。

关于regex - 使用 RegEx 解析 Transact SQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6157644/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com