我不精通编码。在这里找到了解决方案:使用 ForEach-Object 扫描日志文件并替换文本需要很长时间
但是,当查找表中的字符串包含括号(或)时,会遇到错误。
非常感谢任何帮助。
$lookupTable = @{
"Hello (1234)" = "new string 1"
"Some'thing (2023)" = "other"
}
$inputfile = "c:\somewhere\*.*"
Get-ChildItem $inputfile -Filter *.txt | ForEach-Object {
$outfile = Join-Path -Path "c:\else\" -ChildPath ('{0}{1}_new' -f $_BaseName, $_.Extension)
$regexLookup = '({0})' -f (($lookupTable.Keys | ForEach-Object { [regex]::escape($_) }) -join '|')
$writer = [System.IO.StreamWriter]::new($outfile, $true)
Switch -regex -file $_ {
$regexLookup {
$line = $_
$match = [regex]::Match($line, $regexLookup)
while ($match.Success) {
$line = $line -replace $match.Value, $lookupTable[[regex]::Unescape($match.Value)]
$match = $match.NextMatch()
}
$writer.WriteLine($line)
}
default { $write.Writeline($_) }
}
$writer.flush()
$writer.Dispose()
}
我得到的错误是:
正则表达式模式 Hello (1234) 无效。
在 c:\wheremyfileis.ps1:....
- $line = $line - 替换 $match.Value, $lookupTable[[正则表达式 ...
出现您遇到的问题是因为括号是正则表达式中的特殊字符。当它们出现在您的查找键中时,它们将被解释为搜索模式的一部分,从而导致错误。
您已经在脚本中使用了
[regex]::escape($_)
,它应该转义正则表达式中的特殊字符,但这似乎不起作用。我对您的代码做了一些调整,现在它在我的机器上按预期工作:
$lookupTable = @{
"Hello (1234)" = "new string 1"
"Some'thing (2023)" = "other"
}
$inputfile = "c:\somewhere\*.*"
Get-ChildItem $inputfile -Filter *.txt | ForEach-Object {
$outfile = Join-Path -Path "c:\else\" -ChildPath ('{0}_new{1}' -f $_.BaseName, $_.Extension)
$regexLookup = '({0})' -f (($lookupTable.Keys | ForEach-Object { [regex]::escape($_) }) -join '|')
$writer = [System.IO.StreamWriter]::new($outfile, $true)
Switch -regex -file $_ {
$regexLookup {
$line = $_
$match = [regex]::Match($line, $regexLookup)
while ($match.Success) {
$escapedMatch = [regex]::Escape($match.Value)
$line = $line -replace $escapedMatch, $lookupTable[$match.Value]
$match = $match.NextMatch()
}
$writer.WriteLine($line)
}
default { $writer.Writeline($_) }
}
$writer.flush()
$writer.Dispose()
}
我调整了
-replace
操作以使用 $match.Value
的转义版本,以确保正确处理匹配中的任何特殊字符,并确保用于在 $lookupTable
中查找替换字符串的键是未转义的匹配值。最后,我更改了您的代码,使文件扩展名保持不变,并在最后一个句点之前附加 _new
。