匹配Powershell中两个单词之间的所有内容

时间:2014-09-03 08:03:43

标签: regex powershell match

我在EXEC SQL --- END-EXEC的块之间有一个带有SQL查询的大文本文件。

我需要介于EXEC SQL --- END-EXEC之间的所有内容。关键字。样本输入在下面。

这就是我想要做的。如果有一个EXEC SQL块--- END-EXEC,我可以获取内容。但是,如果有多个EXEC SQL --- END-EXEC。块,我失败了。

a)将文件作为字符串读取。

为了将整个文件作为字符串读取,我正在使用

$content = [io.file]::ReadAllText("$pathtofile")
$content = $content -replace "\s*`n", " " 

 (p.s. I'm using V2.0 so cannot use -raw option)

b)然后我这样做以匹配EXEC关键字之间的所有内容。

$result = $content -match "EXEC(.*)EXEC"
$matches[0] > D:\result.txt

输入:

   * ABCD ABCD ABCD BLAH BLAH BLAH - This is some text preceding EXEC SQL

    **EXEC SQL** 
    DECLARE TMPMOTT-CUR CURSOR FOR 
          SELECT KONTYP                     
                ,BFDAT                       
                ,MARK 
                ,MOTT 
                ,AVS     
                ,BEL                      
                ,OKLBE                  
          FROM  ABCBEFGH                      
          ORDER BY MOTT                  

    **END-EXEC**.                               

    * ABCD ABCD ABCD BLAH BLAH BLAH  - This is some text after END-EXEC. 

3 个答案:

答案 0 :(得分:6)

您需要使用lazy quantifier来确保您的正则表达式分别与每个EXEC块匹配。您可以使用单个正则表达式操作收集所有匹配项:

$regex = [regex] '(?is)(?<=\bEXEC SQL\b).*?(?=\bEND-EXEC\b)'
$allmatches = $regex.Matches($subject);

<强>解释

(?is)         # Case-insensitive matching, dot matches newline
(?<=          # Assert that this matches before the current position:
 \b           # Start of a word
 EXEC\ SQL    # Literal text "EXEC SQL"
 \b           # End of word
)             # End of lookbehind assertion
.*?           # Match any number of characters, as few as possible
(?=           # until it's possible to match the following at the current position:
 \bEND-EXEC\b # the words "END-EXEC"
)             # End of lookahead assertion

答案 1 :(得分:2)

或者:

(?<=\*\*EXEC SQL\*\*)[\s\S]*(?=\*\*END-EXEC\*\*)

使用多线模式

答案 2 :(得分:2)

$script = Get-Content D:\temp\script.sql

$in = $false

$script | %{
    if ($_.Contains("EXEC SQL"))
        { $in = $true }
    elseif ($_.Contains("END-EXEC"))
        { $in = $false; }
    elseif ($in)
        { Write-Host $_ } # Or Out-File ...
}