正则表达式适用于 regex101,但不适用于 powershell...为什么?

sha*_*020 2 regex powershell

我有这个测试数据:

^Test data



This is all just test data 


testing 123
ABC>space "ABC"

ABC>
Run Code Online (Sandbox Code Playgroud)

我已经在 regex101.com 上设置了一个正则表达式 (^\^|ERROR).*((|\n|\r|\w|\W)?)+(?=ABC>)

该表达式返回的正是我在网站上想要的内容:

在此输入图像描述

我正在使用我编写的这个 powershell 来获取与上面内容类似的内容并循环遍历文件,并查找相同正则表达式的匹配项。

$files = gci "\\server\path"
$content = @()


ForEach($file in $files){
    # Set script name
    $scriptname = "ABC TEST_081722"

    # Get the name of the task for the logfile's filename. 
    $taskname = "THIS IS A TEST!!!" 

    # Create log file with a datestamp MMDDYY
    $datestamp = (get-date).ToString('MMddyy')
    $logfilepath = "\\server\path\Logs\$($taskname)\$($file.basename).log"
    $log_dir = "\\server\path\Logs\$($taskname)\"

    # Get the content of the log file. We are only interested in getting lines which match a regex for our command line and our output line. 
    $content_raw = get-content $logfilepath -raw

    $content_raw -match "(^\^|ERROR).*((|\n|\r|\w|\W)?)+(?=ABC>)"
    
    Write-host -f yellow $file.fullname
    $matches
    $matches.clear()

                                                                        
    start-sleep -s 2
}
Run Code Online (Sandbox Code Playgroud)

正则表达式在我的三个测试文件中的两个中找到匹配项,但不是第一个与上面的示例具有完全相同字符串内容的文件。为什么它在第二个和第三个文件中找到匹配项,但在第一个文件中却找不到?

第二个和第三个文件的内容是这样的

ABC>W !,MSG

ERROR^BATCH~Batch in use
ABC>space "ABC"
Run Code Online (Sandbox Code Playgroud)

所以这两个文件没有以“^”符号开头的行。它以“ERROR”开头,我用正则表达式中的 OR 语句来解释它。我只是不明白它如何能够找到以“ERROR”开头的行 find,但找不到第一个文件中以“^”克拉开头的行。

mkl*_*nt0 5

请尝试以下正则表达式:

(?sm)(?:^\^|^ERROR).*?(?=\r?\nABC>)

注意:这是正则表达式的简化工作版本(没有捕获组);正则表达式正确形式是,原因如下所述。(?m)(^\^|^ERROR).*((|\n|\r|\w|\W)?)+(?=ABC>)

请注意,PowerShell 的运算符默认情况下不区分大小写(PowerShell 通常也是如此)。为了区分大小写,请使用c- 前缀的运算符变体,即-cmatch在本例中。

请参阅此 regex101.com 页面,您可以在其中以交互方式试验文件中的文本。


至于你尝试过的

  • ^如果regex 选项有效,则仅在各行的开头匹配,您可以使用内联语法激活该选项- 请注意,与 PowerShell 不同,regex101.com默认情况下打开此选项(请参阅选项字母,例如正则表达式输入字段的右侧),这可以解释为什么您没有在那里看到问题。MultiLine(?m)gm

    • 同样,(?s)激活正则SingleLine表达式选项,这也使.匹配换行符(\n)。
  • ^\^|ERROR仅将输入开始/行元^字符应用于(转义)^字符,而不应用于ERROR交替 ( |) 的另一侧。

    • 您的测试数据不在输入文件的最开始处(如屏幕截图所示),导致^在缺少(?m).
    • 相反,因为子字符串ERROR(意外地)没有定,所以它仍然匹配(但会匹配行上的任何位置)。

笔记:

  • 截至撰写本文时,regex101.com还没有专门的 PowerShell 支持,并且最接近的近似值 .NET (C#) 的默认值与 PowerShell 的默认值不一致

  • 有关如何将 regex101.com 与 PowerShell 结合使用的指南,包括指向将来引入 PowerShell 支持的功能请求的链接,请参阅此答案

  • 很高兴听到这个消息,@RavinderSingh13。总结一下:您_可以_已经使 regex101.com 使用 PowerShell,但是 (a) 您需要(首先选择风格“.NET (C#)”并)调整默认匹配选项,以及 (b) 如果您的“... '` 封闭的 PowerShell 正则表达式包含 `"` 或 `'`,您需要修改它以满足 C# 逐字字符串的语法。希望 [引入特定 PowerShell 支持的功能请求](https://github.com /firasdib/Regex101/issues/1838),如果实施,将变得不必要。如果您也希望看到它实施,我建议对其进行投票。 (2认同)