You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell正则负前瞻失效:如何排除含#KEINERW的参数段

问题

需要用PowerShell的Select-String(或通用正则)匹配SQL中不含#KEINERW的@PAR开头参数所在的INSERT INTO #BASIS_VARIABLEN到EXEC sp_executesql @sql代码段,但当前正则的负前瞻未生效,仍会匹配包含#KEINERW的参数段。

原SQL片段

INSERT INTO #BASIS_VARIABLEN
        select ''tagid'' as ParameterTyp,IdentCode as Variable 
        from R34_META_DELIVERY.zeit.Tag t
        where 1=1 '+dbo.SVF_GetAuswahlEinschraenkung('t.IdentCode',@PAR_MONAT_Stichtag)+'
        
        INSERT INTO #BASIS_VARIABLEN
        select ''bankid'' as ParameterTyp,BLZ as Variable 
        from R34_ZDW.orga.Bank t
        where 1=1 '+dbo.SVF_GetAuswahlEinschraenkung('t.BLZ',@PAR_BLZ)

        INSERT INTO #BASIS_VARIABLEN
        select ''segmentid'' as ParameterTyp,Segment as Variable 
        from R34_ZDW.orga.Bank t
        where 1=1 '+dbo.SVF_GetAuswahlEinschraenkung('t.Segment',@PAR#KEINERW_SEG_Segment)  

EXEC sp_executesql @sql

期望匹配结果

INSERT INTO #BASIS_VARIABLEN
        select ''tagid'' as ParameterTyp,IdentCode as Variable 
        from R34_META_DELIVERY.zeit.Tag t
        where 1=1 '+dbo.SVF_GetAuswahlEinschraenkung('t.IdentCode',@PAR_MONAT_Stichtag)+'

        INSERT INTO #BASIS_VARIABLEN
        select ''bankid'' as ParameterTyp,BLZ as Variable 
        from R34_ZDW.orga.Bank t
        where 1=1 '+dbo.SVF_GetAuswahlEinschraenkung('t.BLZ',@PAR_BLZ)

EXEC sp_executesql @sql

当前PowerShell脚本(核心正则问题)

$OutputFile = "C:\Users\WRSKOI\Documents\Check_USP_VW\outfile.txt"
$ErrorFile = "C:\Users\WRSKOI\Documents\Check_USP_VW\errorfile.txt"

# Create or overwrite the output and error files
New-Item -ItemType File -Path $OutputFile -Force | Out-Null
New-Item -ItemType File -Path $ErrorFile -Force | Out-Null

# 问题正则:负前瞻未生效
$RegexPattern = "(?s)INSERT\sINTO\s#BASIS_VARIABLEN.*?@PAR_(?!#KEINERW)(?:TAG|MONAT|DATUM|DATUMVONBIS|BLZ|SEG|BER|GES|MAR|SPR|KSG|KST|REF|TEXT|KTO|TEXTAREA)[\w-]*.*?EXEC\s+sp_executesql\s+@sql"

# Get all .txt files in the specified directory (recursively)
Get-ChildItem -Path "C:\Users\WRSKOI\Documents\Check_USP_VW\TestUSP" -Filter "*.txt" -Recurse | ForEach-Object {
    
    try {
        $File = $_.FullName

        # Read the entire file as a single string for multiline regex matching
        $FileContent = Get-Content -Path $File -Raw

        # Use Select-String to match multiline pattern in the content
        $Matches = [regex]::Matches($FileContent, $RegexPattern)

        # If any matches are found, write them to the output file
        if ($Matches) {
            foreach ($Match in $Matches) {
                $LineNumber = ($FileContent.Substring(0, $Match.Index).Split("`n").Count) # Calculate line number
                $Output = "File: $File, Line: $LineNumber, Match: $($Match.Value)"
                Add-Content -Path $OutputFile -Value $Output
            }
        }
    }
    catch {
        # Log any exceptions to the error file
        $_.Exception.Message | Add-Content -Path $ErrorFile
    }
}

解决方案

问题根源

  1. 原正则的负前瞻(?!#KEINERW)绑定的是@PAR_,但目标违规参数是@PAR#KEINERW(无下划线),导致负前瞻完全没命中目标位置。
  2. .*?的非贪婪匹配无法阻止包含违规参数的内容被纳入匹配范围。

修正后的正则

(?s)(INSERT\sINTO\s#BASIS_VARIABLEN(?:(?!@PAR#KEINERW).)*?)EXEC\s+sp_executesql\s+@sql

正则解释

  • (?s):单行模式,让.匹配换行符,支持跨多行匹配
  • INSERT\sINTO\s#BASIS_VARIABLEN:匹配代码段起始标记
  • (?:(?!@PAR#KEINERW).)*?:核心排除逻辑——非捕获组,逐个字符检查,只要当前位置后不是@PAR#KEINERW就匹配该字符,直到遇到结束标记(非贪婪匹配避免过度匹配)
  • EXEC\s+sp_executesql\s+@sql:匹配代码段结束标记

脚本替换说明

将脚本中的$RegexPattern替换为上述修正后的正则即可,无需修改其他逻辑。该正则符合PCRE标准,可直接复用至Python、Java、C#等其他语言。

内容的提问来源于stack exchange,提问作者StingerWolf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 14:07:28