I am studying PowerShell. I want to know how to check if a string contains any substring in an array in PowerShell. I know how to do the same in Python. The code is given below:
any(substring in string for substring in substring_list) Is there similar code available in PowerShell?
My PowerShell code is given below.
$a = @('one', 'two', 'three') $s = "one is first" I want to validate $s with $a. If any string in $a is present in $s then return True. Is it possible in PowerShell?
8 Answers
Using the actual variables in the question for simplicity:
$a = @('one', 'two', 'three') $s = "one is first" $null -ne ($a | ? { $s -match $_ }) # Returns $true Modifying $s to not include anything in $a:
$s = "something else entirely" $null -ne ($a | ? { $s -match $_ }) # Returns $false (That's about 25% fewer characters than chingNotCHing's answer, using the same variable names of course :-)
2($substring_list | %{$string.contains($_)}) -contains $true should strictly follow your one-liner
1Michael Sorens' code answer works best to avoid the pitfall of partial substrings matching. It just needs a slight regex modification. If you have the string $s = "oner is first", the code would still return true since 'one' would match 'oner' (a match in PowerShell means the second string contains the first string.
$a = @('one', 'two', 'three') $s = "oner is first" $null -ne ($a | ? { $s -match $_ }) # Returns $true Add some regex for word boundary '\b' and the r on 'oner' will now return false:
$null -ne ($a | ? { $s -match "\b$($_)\b" }) # Returns $false For PowerShell ver. 5.0+
Instead of,
$null -ne ($a | ? { $s -match $_ }) try this simpler version:
$q = "Sun" $p = "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" [bool]($p -match $q) This returns $True if substring $q is in the array of string $p.
Another Example:
if ($p -match $q) { Write-Host "Match on Sun !" } 3(I know it's an older thread but at least I might help people looking at this in the future.)
Any response given that uses -match will produce incorrect answers. Example: $a -match $b will produce false negatives if $b is "."
A better answer would be to use .Contains - but it's case sensitive so you'd have to set all strings to upper or lower case before comparing:
$a = @('one', 'two', 'three') $s = "one is first" $a | ForEach-Object {If ($s.toLower().Contains($_.toLower())) {$True}} Returns $True
$a = @('one', 'two', 'three') $s = "x is first" $a | ForEach-Object {If ($s.toLower().Contains($_.toLower())) {$True}} Returns nothing
You could tweak it to return $True or $False if you'd want, but IMO the above is easier.
0I'm amazed that in 6 years nobody has given this more simple and readable answer
$a = @("one","two","three") $s = "one1 is first" ($s -match ($a -join '|')) #return True So simply implode the array into a string using vertical bar "|" , as this is the alternation (the "OR" operator) in regex.
Also keep in mind that the accepted answer will not search for exact match. If you want exact match you can use the \b (word boundary)
$a = @("one","two","three") $s = "one1 is first" ($s -match '\b('+($a -join '|')+')\b') #return False One way to do this:
$array = @("test", "one") $str = "oneortwo" $array|foreach { if ($str -match $_) { echo "$_ is a substring of $str" } } 0It is possible to select a subset of strings containing any of the strings like this:
$array = @("a", "b") $source = @("aqw", "brt", "cow") $source | where { $found = $FALSE foreach($arr in $array){ if($_.Contains($arr)){ $found = $TRUE } if($found -eq $TRUE){ break } } $found }