5

I have an array with Strings, let´s say

$data = @(
"Haus",
"Maus",
"Laus",
"Schnitzel",
"Elefant"
)

I want to check it against multiple Regex from an array.

$regexChecks = @(
".*aus.*",
".*fant.*"
)

I tried something like this

$test = $data |? {$regexChecks -notmatch $_}

Write-Host $test

I expect only the String "Schnitzel" as output.

2 Answers 2

8

you can put the regex as a string. This would only return Schnitzel

$data = @(
"Haus",
"Maus",
"Laus",
"Schnitzel",
"Elefant"
)

$Regex = '.*Schnitzel.*'

$test = $data | ? { $_ -match $Regex }

Write-Host $test

if you want to check more than one regex, use | to seperate them

This would output Schnitzel and Maus

$Regex = '.*Schnitzel.*|.*Maus.*'

This would return Schnitzel, Maus, Laus and Haus

$Regex = '.*Schnitzel.*|.*aus.*'

EDIT:

You can also have a regex array, and join them with |:

$RegexArray = @(
    '.*Schnitzel.*',
    '.*Maus.*'
)

$Regex = $RegexArray -join '|'

$test = $data | ? { $_ -match $Regex }
2
  • 1
    ah i was maybe a bit unclear, this example is oversimplifyed. I have a high amount of regex i want to check and store in an array... Oh now i see your edit that should do the trick! Commented Dec 11, 2018 at 9:09
  • 1
    @SteffenBauer I hope so, otherwise feel free to ask. I'm craving a Schnitzel now
    – SimonS
    Commented Dec 11, 2018 at 9:12
5

Regular expression matches are much slower operations that literal comparisons (-eq) or even wildcard matches (-like), so you should reduce the number of comparisons as much as possible. Since you have an array of regular expressions you can simply merge them into a single one like this:

$regexChecks = '.*aus.*', '.*fant.*'
$re = $regexChecks -join '|'

If you want multiple literal strings matched you can tell PowerShell to escape them first (just in case they contain special characters like dots, square brackets, etc.):

$re = ($regexChecks | ForEach-Object {[regex]::Escape($_)}) -join '|'

Also, you don't need to add leading and trailing .* to your expressions, because regular expressions aren't anchored by default. Just leave them out.

$regexChecks = 'aus', 'fant'
$re = ($regexChecks | ForEach-Object {[regex]::Escape($_)}) -join '|'

You also don't need Where-Object or ForEach-Object to enumerate the elements of an array, because PowerShell operators work as enumerators themselves. Simply use the operator on the array directly:

$test = $data -match $re
1
  • 2
    +1 for having an answer with more knowledge than mine. didn't know about omitting the .* and also didn't consider escape. nice!
    – SimonS
    Commented Dec 11, 2018 at 9:22

Not the answer you're looking for? Browse other questions tagged or ask your own question.