Brad
Brad

Reputation: 2185

Case-insensitive PowerShell replacement

I have the following PowerShell script:

$RegExplorer = Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters
$NullSessionPipes = "$($RegExplorer.NullSessionPipes)"
$NullSessionPipes
$NullSessionPipes =  $NullSessionPipes.replace("browser", "")
$NullSessionPipes

The script works fine as long as the registry key examining exactly matches the case I've specified - "browser".

However if the case was different in the registry key say "BROWSER" or "Browser" it doesn't do the replacement.

I'm looking for some way to make string.replace case insensitive. I know I could convert the string using .tolower or .toupper first to make comparison easier, but I don't know if this particular registry key or applications which access it are case sensitive, so I don't want to change the case of existing key.

Is there an easy way to do this?

Upvotes: 35

Views: 76454

Answers (5)

nmbell
nmbell

Reputation: 611

The String.Replace method has two different overloads that allows a case-insensitive replacement:

Replace(String, String, StringComparison)

Replace(String, String, Boolean, CultureInfo)

For the first one, you need to pick a StringComparison that ignores case, e.g. OrdinalIgnoreCase. For the second one, it's the Boolean that controls case sensitivity; a null for the CultureInfo uses the current culture.

Using these in PowerShell 7 would look like:

$s = 'All the HIP cats'
$s.Replace('hip','cool')                     # doesn't work: All the HIP cats
$s.Replace('hip','cool','OrdinalIgnoreCase') # works       : All the cool cats
$s.Replace('hip','cool',$true,$null)         # works       : All the cool cats

Upvotes: 5

Ryan Shillington
Ryan Shillington

Reputation: 25097

Call me pedantic but while nobody here was outright wrong, nobody provided the correct code for the final solution either.

You need to change this line:

$NullSessionPipes =  $NullSessionPipes.replace("browser", "")

to this:

$NullSessionPipes =  $NullSessionPipes -ireplace [regex]::Escape("browser"), ""

The strange [regex] text isn't strictly necessary as long as there are no regular expression characters (ex. *+[](), etc) in your string. But you're safer with it. This syntax works with variables too:

$NullSessionPipes =  $NullSessionPipes -ireplace [regex]::Escape($stringToReplace), $stringToReplaceItWith

Upvotes: 54

MisterSeajay
MisterSeajay

Reputation: 4659

The .Replace method doesn't have a case-insensitive option:

String.Replace method

...This method performs an ordinal (case-sensitive and culture-insensitive) search...

https://msdn.microsoft.com/en-us/library/fk49wtc1(v=vs.110).aspx

The other answers to this question suggest using -replace or -ireplace, which is fine if you want to use regex replacement. However, as @Bob mentions in his (her?) comments this isn't always appropriate. An example might be if you want to include a literal string such as $_ in the replacement text.

One trick borrowed from other case-sensitive places is to convert the "input" string and the "search" string to lower case:

[PS]> "TeXT".ToLower().Replace("text","NewString")
NewString

However... this causes the output to be in lower case for anything that doesn't match the search string, which may well be unacceptable.

[PS]> "DON'T CHANGE MY TeXT".ToLower().Replace("text","NewString")
don't change my NewString

Upvotes: 5

Shay Levy
Shay Levy

Reputation: 126732

NullSessionPipes is a multi-string value and the replace method (in addition of being case-sensitive) may fail if there's more than one string in it. You can use the -replace operator. By default, all comparison operators are case-insensitive. Case-sensitive operators starts with 'c', like: -creplace,-ceq, etc.

Operators that starts with 'i' are case-insensitive, like -ireplace,-ieq, and they are the same as -replace, -ieq.

See the about_Comparison_Operators for more information.

Upvotes: 13

Andy Arismendi
Andy Arismendi

Reputation: 52577

Use a regular expression replacement instead:

$RegExplorer =  Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters
$NullSessionPipes = "$($RegExplorer.NullSessionPipes)"
$NullSessionPipes  
$NullSessionPipes = $NullSessionPipes -replace "browser", ""
$NullSessionPipes 

Upvotes: 6

Related Questions