我有一个很长的SQL脚本,我想识别SQL列名称的出现并将它们替换为字典中的条目,但是我想保留参数名称。使用负向前瞻(或向后看?)从SQL中提取列名称
列名的格式为schema.TableName.ColumnName
,TableName.ColumnName
或ColumnName
。而参数名称的格式总是@parameterName
。
所以给这个脚本(人为的例子):
DECLARE @foo varchar(max) = '123'
DECLARE @bar varchar(max) = '456'
SELECT foo, table.bar, @bar FROM table ORDER BY table.foo DESC
我想匹配:
foo
table.bar
table
table.foo
我第一次写一个简单的正则表达式匹配列名:
([A-Za-z_]+[0-9A-Za-z_]*)(\.[A-Za-z_]+[0-9A-Za-z_])*(\.[A-Za-z_]+[0-9A-Za-z_])*
(这是从左到右构建的一点小技巧,因此第一个匹配的组是或者是列名(如果是单标签d),表名(如果双重标记)或模式名(如果完全限定),但这不是一个大问题)。
...除了这个正则表达式也选择紧接着at符号之后的那部分参数。所以我需要修改它,以便它不符合参数。我添加了一个负向后断言(?<!\@)
相匹配的领先的@
前缀,那么取消比赛,但它不工作:
((?<!\@)([A-Za-z_]+[0-9A-Za-z_]*)(\.[A-Za-z_]+[0-9A-Za-z_])*(\.[A-Za-z_]+[0-9A-Za-z_])*
尽管负向后断言,鉴于输入“@foobar
”它匹配/捕获“@f[oobar]
”,而不是拒绝捕获它。
显然我没有正确使用lookbehind断言。我已经尝试将断言放在父组之内和之外,并且尝试了负向超前断言,但没有任何效果。
@a_horse_with_no_name我在SQL以外,在C#/。NET正则表达式事实上这样做。这是一个将处理数据库的schema + sproc转储的程序。 – Dai