1

So I got this regex expression to work in Regex101 and it captures exactly what I want to capture. https://regex101.com/r/aJ1bZ4/3

But when I try the same thing in powershell all I get is the first set of matches. I've tried using the (?s:), the (?m:) but none of these modifiers seem to do the job. Here is my powershell script.

$reportTitleList = type ReportExecution.log | Out-String |
where {$_ -match "(?<date>\d{4}\/\d{2}\/\d{2}).*ID=(?<reportID>.*):.*Started.*Title=(?<reportName>.*)\[.*\n.*Begin ....... (?<reportHash>.*)"} |
foreach {
    new-object PSObject -prop @{
        Date=$matches['date']
        ReportID=$matches['reportID']
        ReportName=$matches['reportName']
        ReportHash=$matches['reportHash']
    }
}

$reportTitleList > reportTitleList.txt

What am I doing wrong? Why am I not getting all the matches as the regex101 example?

1
  • The powershell pipeline is getting individual lines of the file and passing them into where, but your regex is a multiline regex containing \n. The regex will never see a newline character, or the "started", "begin", "end" lines at once, so it won't match properly. Commented May 4, 2016 at 21:36

2 Answers 2

1

-match only find the first match. To use a global search you need to use [regex]::Matches() or Select-String with the -AllMatches switch. Ex:

#In PoweShell 3.0+ you can replace `Get-Content | Out-String` with `Get-Content -Raw`
$reportlist = Get-Content -Path ReportExecution.log | Out-String |
Select-String -Pattern $pattern -AllMatches |
Select-Object -ExpandProperty Matches |
Select-Object @{n="Date";e={$_.Groups["date"]}},
              @{n="ReportID";e={$_.Groups["reportID"]}},
              @{n="ReportName";e={$_.Groups["reportName"]}},
              @{n="ReportHash";e={$_.Groups["reportHash"]}}

#Show output
$reportlist

Output:

Date       ReportID ReportName                                                             ReportHash                       
----       -------- ----------                                                             ----------                       
2015/03/23 578      Calendar Day Activity/Calendar Day Activity                            38C19F4E790446709B8C7A32FF97BC...
2015/03/23 861      Program Format Report/Program Format Report                            3C9CB2150AF14B15A1B361729C007B...
2015/03/23 1077     Multi-Station Program Availability/Multi-Station Program Availability  52526430EE4E401BA4376B38A2D88B...
2015/03/23 1299     Program Audit Trail/Program Audit Trail                                FDD1B7D9F34E46549A377A17B9A7A1...
2015/03/23 1541     Program Availability/Program Availability                              843B44F4475C4950A7784C8961B642...
2015/03/23 1756     Program Description Export/Program Description Export                  E5800A76C68E4D5281B8D680DB2E93...
Sign up to request clarification or add additional context in comments.

7 Comments

so the $pattern wold just be the same regex101 pattern or do I need to modify it?
Pattern should be the same regex
Data field? The hash you mean? It's truncated because of the console/screen buffer width, but you can access it by using the property. Ex: $reportlist[0].ReportHash (first item only). To export this to a file you should use Export-CSV or create a string etc. You should not redirect the screen output itself as it will truncate data.
So I am using the same method on another set of data and again regex101 matches while powershell doesnt regex101.com/r/xG8oX2/1 $reportLayoutIDList = Get-Content -Path bigOptions.txt | Out-String | Select-String -Pattern $pattern2 -AllMatches | Select-Object -ExpandProperty Matches | Select-Object @{n="ReportHash";e={$_.Groups["reportHash"]}}, @{n="LayoutID";e={$_.Groups["reportLayoutID"]}};$reportLayoutIDList Is there a modifier I need to use in the regex for powershell?
The problem is your linebreaks. In windows, linebreaks are CRLF (\r\n) while in UNIX etc. they're just LF \n. So either you need to modify the input to only use LF or you need to replace \n with \r\n in your regex to make it Windows-compatible. This should have been a different SO-question. :-)
|
1

-match returns as soon as it finds a match (they should have a -matches operator right?). If you want multiple matches, use:

$mymatches = [regex]::matches($input,$pattern)

output will be different than -match, however, and you'll have to massage it a bit, something like: (see here for another example of conversion)

$mymatches | ForEach-Object { if ( $_.Success) { echo $_.value}}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.