1

I can't seem to find an example of what I'm trying to do here.

I have a list of regular expressions that I'm searching through for each line of a csv file and they work great if everything is in upper case. However, my search is case sensitive and I can't figure out how to make it case insensitive, without modifying each of the regular expressions with something like ?i. Is it possible to modify what I'm doing here in a simple way?

Bonus Points! I'm searching with thousands of regular expressions and it seems to take a long time on that part. If you happen to know of a faster way to search each line for all of the regex's, please share.

    $file = New-Object System.IO.StreamReader ($CSVFile)  # Input Stream
        while (($text = $file.ReadLine()) -ne $null ){
            foreach ($RX in $SearchList){
                foreach ($match in ([regex]$RX).Matches($text)) {
                        write-host "Match found: " $match.value -ForegroundColor Red     
                }
            }
        }
    $file.close();

Thanks for any help with this!

MrMr
  • 483
  • 1
  • 9
  • 25
  • Possible duplicate of [Pass regex options to PowerShell \[regex\] type](https://stackoverflow.com/questions/12977338/pass-regex-options-to-powershell-regex-type) – jrider Dec 12 '18 at 22:48
  • as jrider pointed out, if you use the `[regex]` type, then you are case-sensitive by default. you will need to use the required options to change that. ///// if you use the built in `-match` you get case-insensitive by default. ///// if you have thousands of regex patterns, why are you trying them one-at-a-time? use the `|` to get an OR and you can feed the entire list as one test. – Lee_Dailey Dec 12 '18 at 22:54
  • 1
    Note that you can specify regex options inline in the regex as `(?i)` for case insensitive. – NetMage Dec 12 '18 at 23:27

2 Answers2

2

Add this line just inside of your foreach ($RX in $SearchList){:

$RX = [regex]::new($RX,([regex]$RX).Options -bor [System.Text.RegularExpressions.RegexOptions]::IgnoreCase)

This ensures that $RX is a [regex] object, as well as adds the IgnoreCase option to whatever options were present.

NH.
  • 2,240
  • 2
  • 23
  • 37
2

To speed it up, you can do two things before searching: read the entire file to memory and create all your regex-objects...

$reList = $SearchList | ForEach-Object { [regex]$_ } # adapt the regex here

$lines = [System.IO.File]::ReadAllLines($CSVFile)

You really need thousands of regexs?

The new syntax becomes:

foreach($line in $lines) {
    foreach($re in $reList) {

    }
}
Palansen
  • 311
  • 2
  • 7
  • This seems like a great idea. However, I'm not sure how to implement the actual searching portion. I tried $reList | Where-Object {$_ -match $lines} I also tried a foreach, but I don't seem to get getting any matches. – MrMr Dec 13 '18 at 15:04
  • It looks like this works: foreach ($match in ($reList).Matches($lines)) {} However, I also need to capture the line it was found on. I created a new question for this. https://stackoverflow.com/questions/53764919/speeding-up-regular-expression-matching – MrMr Dec 13 '18 at 15:17
  • Also, I can't seem to access the values in $reList. Tried $reList[0].options.value__ but it returns 0 – MrMr Dec 13 '18 at 18:57
  • The syntax is the same as your original. I've updated the post. – Palansen Dec 13 '18 at 19:03
  • okay great, that really helps, thank you! I tested this out and the relist made it much faster. However, the $lines line didn't seem to have much of an effect on speed. I tried it both ways using the reList you gave me. Thank you! PS Check out my other question, if you post this, i can give you credit for the answer. =) – MrMr Dec 13 '18 at 19:39