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

Regex在regex101可用但PowerShell中失效,求助原因

问题原因与解决办法

问题说明

测试数据示例:

^Test data



This is all just test data 


testing 123
ABC>space "ABC"

ABC>

在正则测试工具中使用(^\^|ERROR).*((|\n|\r|\w|\W)?)+(?=ABC>)能正常匹配,但PowerShell脚本中仅能匹配以ERROR开头的文件,无法匹配以^开头的文件。脚本代码如下:

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

ForEach($file in $files){
    $scriptname = "ABC TEST_081722"
    $taskname = "THIS IS A TEST!!!" 
    $datestamp = (get-date).ToString('MMddyy')
    $logfilepath = "\\server\path\Logs\$($taskname)\$($file.basename).log"
    $log_dir = "\\server\path\Logs\$($taskname)\"

    $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
}

核心原因

PowerShell基于.NET正则引擎,默认未启用DOTALL(单行)模式,该模式下.仅匹配除换行符外的任意字符;而你在测试工具中大概率开启了DOTALL模式,让.能跨多行匹配。

你的正则中,.*在未开启DOTALL时只能匹配^Test data这一行内容,无法覆盖后续的换行和多行文本,导致正则无法到达(?=ABC>)的断言位置,最终匹配失败。而ERROR开头的文件可能内容无换行或换行位置不影响匹配,所以能成功。

解决办法

方法1:开启DOTALL模式

在正则开头添加(?s)标记,强制.匹配所有字符(包括换行),同时简化冗余的正则部分:

$content_raw -match "(?s)(^\^|ERROR).*?(?=ABC>)"

用.*?非贪婪匹配代替原正则中冗余的((|\n|\r|\w|\W)?)+,避免过度匹配到最后一个ABC>。

方法2:用[\s\S]替代.

[\s\S]能匹配所有空白与非空白字符(即所有字符,包括换行),无需额外开启模式:

$content_raw -match "(^\^|ERROR)[\s\S]*?(?=ABC>)"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 01:06:20