2

I'm having a larger foreach loop code but need to get below code executed without casesensitive.

Below code snippet returns false, how can I ignore the casesensitive .contains() and the condition as true?

$a='aa0855'
$b='AA0855 Sample'
$b.Contains($a)

Expected value is true. Above code is tried with 2 variables and it returns false.

mklement0
  • 382,024
  • 64
  • 607
  • 775

2 Answers2

3

The .Contains() .NET string method is indeed case-sensitive - invariably in Windows PowerShell, and by default in PowerShell (Core) 7+.

Thus, in PowerShell (Core) 7+ you can do:

# PS 7+ only
# -> $true
$a='aa0855'; $b='AA0855 Sample'; $b.Contains($a, 'InvariantCultureIgnoreCase')

The second .Contains() argument is converted to an enumeration value of type StringComparison; InvariantCultureIgnoreCase is the same value that PowerShell's operators use by default, i.e. a case-insensitive comparison that is culture-neutral (i.e. performed in the context of the invariant culture).


In Windows PowerShell you have two options, using PowerShell operators, which are case-insensitive by default:

$a='aa0855'; $b='AA0855 Sample'; $b -like "*$a*" 

If $a contains characters that are metacharacters in the context of a wildcard expression, namely * and ?, and [ / ], escape them, either individually with ` or, more simply, in the entire string with [WildcardPattern]::Escape():

$a='aa0855'; $b='AA0855 Sample'; $b -like ('*{0}*' -f [WildcardPattern]::Escape($a)) 
$a='aa0855'; $b='AA0855 Sample'; $b -match $a

If $a contains characters that are metacharacters in the context of a regex, such as ., they must be escaped, either individually with \, or, more simply, in the entire string with [regex]::Escape():

$a='aa0855'; $b='AA0855 Sample'; $b -match [regex]::Escape($a)

Alternatively, use different / additional .NET APIs that are also available in Windows PowerShell:

  • Option C: Look for the index of substring $a in string $b with String.IndexOf(), which can be done case-insensitively; return value -1 indicates that $a isn't a substring of $b:

    $a='aa0855'; $b='AA0855 Sample'
    -1 -ne $b.IndexOf($a, [StringComparison]::InvariantCultureIgnoreCase)
    
    • Note that in this case [StringComparison]::InvariantCultureIgnoreCase, i.e. a value of the exact parameter type must be used to unambiguously target the right method overload; the string shortcut, 'InvariantCultureIgnoreCase', would be ambiguous.
  • Option D: Convert both strings to lowercase before using the (single-argument, case-sensitive) .Contains() overload:

mklement0
  • 382,024
  • 64
  • 607
  • 775
2

Here's another way:

$a='aa0855'; $b='AA0855 Sample'; $b.ToLower().Contains($a.ToLower())

True
mklement0
  • 382,024
  • 64
  • 607
  • 775
js2010
  • 23,033
  • 6
  • 64
  • 66