Powershell:使用哈希表替换字符串中的
好的,我建立了一个哈希表,其中名称是要替换的内容,键是要替换的内容,如下所示:Powershell:使用哈希表替换字符串中的,powershell,replace,hashtable,Powershell,Replace,Hashtable,好的,我建立了一个哈希表,其中名称是要替换的内容,键是要替换的内容,如下所示: $r = @{ "dog" = "canine"; "cat" = "feline"; "eric" = "eric cartman" } 接下来我该怎么办?我试过这个: (Get-Content C:\scripts\test.txt) | Foreach-Object { foreach ( $e in $r.GetEnumerator() ) { $_ -rep
$r = @{
"dog" = "canine";
"cat" = "feline";
"eric" = "eric cartman"
}
接下来我该怎么办?我试过这个:
(Get-Content C:\scripts\test.txt) | Foreach-Object {
foreach ( $e in $r.GetEnumerator() ) {
$_ -replace $e.Name, $e.Value
}
} | Set-Content C:\scripts\test.txt.out
但它根本不起作用,它只是每行写三次,没有替换任何内容
编辑:包含test.txt的内容:
dog
cat
eric
test.txt.out:
dog
dog
dog
cat
cat
cat
eric
eric
eric
这里有一种方法:
$file = Get-Content C:\scripts\test.txt
foreach ($e in $r) {
$file = $file -replace $e.Name, $e.Value
}
Set-Content -Path C:\scripts\test.txt.out -Value $file
之所以每行都要看三次,是因为嵌套的foreach循环。对于文件中的每一行,每个哈希表条目运行一次替换操作。这不会更改源文件,但默认情况下它会输出替换的结果(即使没有更改)
通过先将文件读入变量,然后使用循环替换来更新该变量,可以获得所需的功能。文件内容也不需要单独的foreach循环;replace可以在每个hashtable条目的一次遍历中针对全文运行。我是这样做的
foreach ($i in $HashTable.Keys) {
$myString = $myString -replace $i, $HashTable[$i]
}
根据您的文件和哈希表,您可以考虑以下各种优化:
$regexes = $r.keys | foreach {[System.Text.RegularExpressions.Regex]::Escape($_)}
$regex = [regex]($r.Keys -join '|')
这样做不需要迭代每个键,但现在需要知道匹配了哪个键才能获得替换。另一方面,用字符串替换代替正则表达式替换(或更复杂的字符串拆分和连接过程)可能会更快Regex::Replace
函数:
字符串替换(字符串输入,System.Text.RegularExpressions.MatchEvaluator计算器)
调用此方法,您可以使用脚本块定义一个MatchEvaluator
,如下所示:
$callback = { $r[$args[0].Value] }
在scriptblock中,$args[0]
是一个系统.Text.RegularExpressions.Match
,因此您可以使用其值
属性索引到$r
哈希表中Get Content
返回一个字符串数组,对于-replace
操作符来说,该数组很好,但也意味着额外的循环正在运行[System.IO.File]::ReadAllText
将返回单个字符串,因此正则表达式只需解析一次
$file = [System.IO.File]::ReadAllText("C:\scripts\test.txt")
Get Content
,要使用$regex.Replace
(而不是-Replace
),您需要一个循环:
$file = $file | % { $regex.Replace($_, $callback) }
由于我不是,我可以使用单个替换调用:
$file = $regex.Replace($file, $callback)
$r = @{
"dog" = "canine";
"cat" = "feline";
"eric" = "eric cartman"
}
$regexes = $r.keys | foreach {[System.Text.RegularExpressions.Regex]::Escape($_)}
$regex = [regex]($regexes -join '|')
$callback = { $r[$args[0].Value] }
$file = [System.IO.File]::ReadAllText("C:\scripts\test.txt")
$file = $regex.Replace($file, $callback)
Set-Content -Path C:\scripts\test.txt.out -Value $file
C:\scripts\test.txt的内容是什么?谢谢!工作起来很有魅力。很好@Christian,GetEnumerator()调用并没有真正完成任何事情。已删除。要使其不区分大小写,请使用
$regex=[regex](“(?i)”+($regexes-join'|')