如何使用PowerShell检查T-SQL文件是否在块注释中包含GO语句?

亚历克斯沃达

我需要沿着批处理定界符边界拆分T-SQL脚本文件,并分别执行每个段。拆分很容易。GO语句必须在一行上单独存在,并且只能在空格之前和之后。(例外:GO也可以后面跟数字,而不是变量。我现在暂时忽略这种情况。现在我也忽略了GO之后插入注释的情况)

但是,可以在块注释内找到GO语句(显然会忽略它们)。沿该边界分裂将导致代码损坏。我想检查并拒绝脚本文件,如果它在块注释中包含GO语句。

到目前为止,我已经构建了此正则表达式:

(\/\*)(.?([^\*][^\/])*?)(^(\s*?)go(\s*?)$)(.?([^\/][^\*])*?)(?=(\*\/))

它几乎可以工作,但是仍然存在问题。

拆分和识别不符合要求的文件将在PowerShell中完成。

注意:在此阶段,我们尚未确定将使用解析器。可能的解析器选项仍在研究中

我在regex101.com上通过添加和删除字母进行了测试:

/*
llaa

GO


*/

GO

/*
a
*/

GO
a
/*

GOaaa

*/
a
GO

/*

a

*/
mklement0

尝试以下正则表达式,仅$trueGO找到内部注释时才应产生此正则表达式请注意,它还会GO正确检测到后跟(十进制)数字:

@'
/* a comment with GO, but not on its own line */

/* This GO should be found.
   GO 12  
*/

/* This one is outside a comment */
GO
'@ -match '(?sm)/[*](.(?![*]/))+?^\s*go(\s+\d+)?\s*$'

上述收益$true归因于存在注释嵌入GO 12

  • (?sm)在内嵌选项匝s(化妆.比赛\n太)和m(化妆^$匹配的开始和结束太)。

  • /[*]匹配块注释的开头(*是一个元字符,必须进行转义(\*),以便从字面上进行解释或在字符集([...])中指定,如此处所示)。

  • (.(?![*]/))+?与单个字符(.匹配,而不是跟在原义*/字符后面(使用(?!...),负向超前),一次或多次(+),而不是非贪婪(?)。

    • 这是GO块注释真正匹配的关键
  • ^\s*go匹配行(^的开头,然后可能是空白的空格(\s*),然后是文字go(请注意,PowerShell的-match运算符不区分大小写)。

  • (\s+\d+)??可选地匹配非空字符的空格(\s+),后跟一个或多个(+)数字(\d)。

  • \s*$ 在行尾匹配一个可能为空的空白行。

  • 假设所有块注释的格式正确,则无需匹配其余注释。


为了超出拒绝不想要的输入的范围TheMadTechnician建议使用-split,它可以有效地消除那些GO在输入中嵌入行的块注释

$sanitized = @'
/* a comment with GO, but not on its own line */
before
/* This GO should be found.
   GO 12  
*/
after
/* This one is outside a comment */
GO
...
/* Another comment with a GO.
  foo
GO
*/
last
'@ -split '(?sm)/[*](?:.(?![*]/))+?^\s*go(?:\s+\d+)?\s*$.+?[*]/' -join ''

上面的代码将以下内容存储在变量中$sanitized-请注意,带有嵌入式GO语句的块注释已消失:

/* a comment with GO, but not on its own line */
before

after
/* This one is outside a comment */
GO
...

last

然后,如果您想通过剩余的未注释的有效GO语句将生成的脚本分成组成部分,请执行以下操作

$sanitized -split '(?m)^\s*go(?:\s+\d+)?\s*$'

正如您所指出的,GO它实际上并不是T-SQL的一部分

 GO不是Transact-SQL语句;它是sqlcmdandosql工具和SQL Server Management Studio代码编辑器可识别的命令


至于你尝试什么

你的/\*(.?([^*][^/])*?)^\s*?go子表达式(这里简化)旨在块注释起来开始匹配嵌入GO在确保子无效*/存在; 它会产生误报和误报。

误报示例(匹配,但不应该):

/*a*/
go

错误否定示例(不匹配,但应匹配):

/*a*
go

正如您在评论中所怀疑的那样,问题在于[^*][^/]匹配了对字符,因此匹配行为最终取决于输入字符的数量是奇数还是偶数。使用简化的示例:

# Even number of chars. -> $false, as intended
'*/' -match '^(.?([^*][^/])*?)$'

# Odd number of chars. -> $true(!)
'*/a' -match '^(.?([^*][^/])*?)$'

如上所示,只有否定的前瞻断言可以可靠地排除给定的(多字符)字符串

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何使用Powershell检查重复的多个文件?

如何使用go检查XML文件中是否存在标签?

如何使用Powershell检查特定服务是否存在?

如何使用powershell命令检查变量目录是否存在?

如何使用Powershell检查重复的文件名?

如何使用 PowerShell 从 csv 列中检查空行

如何检查Go中是否存在文件?

我如何检查文件是否在Powershell中包含args [0]参数

如何使用Ansible检查文件中是否存在特定文本块?

如何注释掉包含注释的HTML块

如何在Go中检查地图是否包含密钥?

如何检查Powershell中端口是否打开

如何检查SQL Server中是否执行了任何IF块

如何使用glob检查文件夹中是否包含子文件夹?

使用Powershell检查S3中是否存在文件

如何使用PowerShell或其他方法检查是否写入了网络位置上的文件?

如何使用python语句检查sql表是否存在?

如何使用PowerShell检查Azure Blob容器中是否已存在Blob

如何使用Powershell和Web管理模块检查IIS中是否存在应用程序池?

Jenkins:如何使用 powershell 检查 Nexus 中是否存在服务器目录?

如何使用PHP检查网页是否包含图像文件?

如何使用T-SQL检查逻辑项目组合?

如何使用 SQL Server 检查 then 块中的条件?

如何检查文件中是否包含字符串

删除 Powershell 中的注释块

PowerShell - 如何检查“不包含”子句?

如何检查是否使用`with`语句创建对象?

如何使用JavaScript检查div中是否包含svg?

如何在go中检查文件是否可执行?