如何解决 Replace string 方法的区分大小写问题?
How do I get around the case sensitivity of the Replace string method?
我正在将 SCCM 中几乎所有内容的内容源移动到 DFS 共享,因此我必须更改环境中所有内容的源路径,并且在大多数情况下,我已经它编码出来。不过,我想做一些改进,以便在点击红色大按钮之前清理代码。
例如,Powershell的.Replace
方法是区分大小写的,有时有人在服务器名称中只使用部分名称的大写。
\typNUMloc\
可以是 \typNUMLOC\
或 \TYPNUMloc\
或 \TYPNUMLOC\
。这会产生超大的 If 语句。
我的一个功能是针对驱动程序的(不是驱动程序包,我已经用类似的代码测试过,而且我只有一个输入错误的路径)。为了安全起见,红色大按钮被注释掉了。
$DriverArray = Get-CMDriver | Select CI_ID, ContentSourcePath | Where-Object {$_.ContentSourcePath -Like "\oldNUMsrv\*"}
Foreach ($Driver in $DriverArray) {
$DriverID = $Driver.CI_ID
$CurrPath = $Driver.ContentSourcePath
# Checks and replaces the root path
If ($CurrPath -split '\' -ccontains 'path_dir') {
$NewPath = $CurrPath.Replace("oldNUMsrv\path_dir","dfs\Path-Dir")
#Set-CMDriver -Id $DriverID -DriverSource $NewPath
} ElseIf ($CurrPath -split '\' -ccontains 'Path_dir') {
$NewPath = $CurrPath.Replace("oldNUMsrv\Path_dir","dfs\Path-Dir")
#Set-CMDriver -Id $DriverID -DriverSource $NewPath
} ElseIf ($CurrPath -split '\' -ccontains 'Path_Dir') {
$NewPath = $CurrPath.Replace("oldNUMsrv\Path_Dir","dfs\Path-Dir")
#Set-CMDriver -Id $DriverID -DriverSource $NewPath
} Else {
Write-Host "Bad Path at $DriverID -- $CurrPath" -ForegroundColor Red
}
# Checks again for ones that didn't change propery (case issues)
If ($NewPath -like "\oldNUMsrv\*") {
Write-Host "Bad Path at $DriverID -- $CurrPath" -ForegroundColor Red
}
}
但是如您所知,我不需要执行大量代码。我知道,我可以使用 -replace
或 -ireplace
方法,但我最终在我的路径中添加了额外的反斜杠 (\dfs\Path-Dir
),即使使用 [regex]::escape
.
如何使用不同路径的数组来匹配 $CurrPath
并执行替换?我知道它不起作用,但像这样:
If ($Array -in $CurrPath) {
$NewPath = $CurrPath.Replace($Array, "dfs\Path-Dir"
}
我认为您的问题可能是假设您必须转义替换字符串和模式字符串。事实并非如此。由于您有控制字符(斜杠),因此您需要转义模式字符串。在它的基本形式中,你只需要做这样的事情:
PS C:\Users\Matt> "C:\temp\test\file.php" -replace [regex]::Escape("temp\test"), "another\path"
C:\another\path\file.php
但是我想更进一步。您的 if 语句都在做相对相同的事情。找到一系列字符串并用相同的东西替换它们。 -contains
也不是很必要。另请注意,默认情况下,所有这些比较运算符都不区分大小写。参见 about_comparison_operators
您可以通过构建模式字符串使用更多的正则表达式来简化所有这些。所以假设你的字符串都是唯一的(大小写无关紧要)你可以这样做:
$stringstoReplace = "oldNUMsrv1\path_dir", "oldNUMsrv2\Path_dir", "oldNUMsrv1\Path_Dir"
$regexPattern = ($stringstoReplace | ForEach-Object{[regex]::Escape($_)}) -join "|"
if($CurrPath -match $regexPattern){
$NewPath = $CurrPath -replace $regexPattern,"new\path"
}
您甚至不需要 if
。无论如何,您都可以在所有字符串上使用 -replace
。我只留下了 if
,因为你检查过是否有变化。同样,如果您只是为了解释大小写而创建所有这些语句,那么我的建议是没有实际意义的。
我正在将 SCCM 中几乎所有内容的内容源移动到 DFS 共享,因此我必须更改环境中所有内容的源路径,并且在大多数情况下,我已经它编码出来。不过,我想做一些改进,以便在点击红色大按钮之前清理代码。
例如,Powershell的.Replace
方法是区分大小写的,有时有人在服务器名称中只使用部分名称的大写。
\typNUMloc\
可以是 \typNUMLOC\
或 \TYPNUMloc\
或 \TYPNUMLOC\
。这会产生超大的 If 语句。
我的一个功能是针对驱动程序的(不是驱动程序包,我已经用类似的代码测试过,而且我只有一个输入错误的路径)。为了安全起见,红色大按钮被注释掉了。
$DriverArray = Get-CMDriver | Select CI_ID, ContentSourcePath | Where-Object {$_.ContentSourcePath -Like "\oldNUMsrv\*"}
Foreach ($Driver in $DriverArray) {
$DriverID = $Driver.CI_ID
$CurrPath = $Driver.ContentSourcePath
# Checks and replaces the root path
If ($CurrPath -split '\' -ccontains 'path_dir') {
$NewPath = $CurrPath.Replace("oldNUMsrv\path_dir","dfs\Path-Dir")
#Set-CMDriver -Id $DriverID -DriverSource $NewPath
} ElseIf ($CurrPath -split '\' -ccontains 'Path_dir') {
$NewPath = $CurrPath.Replace("oldNUMsrv\Path_dir","dfs\Path-Dir")
#Set-CMDriver -Id $DriverID -DriverSource $NewPath
} ElseIf ($CurrPath -split '\' -ccontains 'Path_Dir') {
$NewPath = $CurrPath.Replace("oldNUMsrv\Path_Dir","dfs\Path-Dir")
#Set-CMDriver -Id $DriverID -DriverSource $NewPath
} Else {
Write-Host "Bad Path at $DriverID -- $CurrPath" -ForegroundColor Red
}
# Checks again for ones that didn't change propery (case issues)
If ($NewPath -like "\oldNUMsrv\*") {
Write-Host "Bad Path at $DriverID -- $CurrPath" -ForegroundColor Red
}
}
但是如您所知,我不需要执行大量代码。我知道,我可以使用 -replace
或 -ireplace
方法,但我最终在我的路径中添加了额外的反斜杠 (\dfs\Path-Dir
),即使使用 [regex]::escape
.
如何使用不同路径的数组来匹配 $CurrPath
并执行替换?我知道它不起作用,但像这样:
If ($Array -in $CurrPath) {
$NewPath = $CurrPath.Replace($Array, "dfs\Path-Dir"
}
我认为您的问题可能是假设您必须转义替换字符串和模式字符串。事实并非如此。由于您有控制字符(斜杠),因此您需要转义模式字符串。在它的基本形式中,你只需要做这样的事情:
PS C:\Users\Matt> "C:\temp\test\file.php" -replace [regex]::Escape("temp\test"), "another\path"
C:\another\path\file.php
但是我想更进一步。您的 if 语句都在做相对相同的事情。找到一系列字符串并用相同的东西替换它们。 -contains
也不是很必要。另请注意,默认情况下,所有这些比较运算符都不区分大小写。参见 about_comparison_operators
您可以通过构建模式字符串使用更多的正则表达式来简化所有这些。所以假设你的字符串都是唯一的(大小写无关紧要)你可以这样做:
$stringstoReplace = "oldNUMsrv1\path_dir", "oldNUMsrv2\Path_dir", "oldNUMsrv1\Path_Dir"
$regexPattern = ($stringstoReplace | ForEach-Object{[regex]::Escape($_)}) -join "|"
if($CurrPath -match $regexPattern){
$NewPath = $CurrPath -replace $regexPattern,"new\path"
}
您甚至不需要 if
。无论如何,您都可以在所有字符串上使用 -replace
。我只留下了 if
,因为你检查过是否有变化。同样,如果您只是为了解释大小写而创建所有这些语句,那么我的建议是没有实际意义的。