Maybe my reasoning is faulty, but I can\'t get this working.
Here\'s my regex: (Device\\s#\\d(\\n.*)*?(?=\\n\\s*Device\\s#|\\Z))
Try it: http://
With your existing regex, to get a list of all matches in a string, use one of these options:
Option 1
$regex = [regex] '(Device\s#\d(\n.*)*?(?=\n\s*Device\s#|\Z))'
$allmatches = $regex.Matches($yourString);
if ($allmatches.Count > 0) {
# Get the individual matches with $allmatches.Item[]
} else {
# Nah, no match
}
Option 2
$resultlist = new-object System.Collections.Specialized.StringCollection
$regex = [regex] '(Device\s#\d(\n.*)*?(?=\n\s*Device\s#|\Z))'
$match = $regex.Match($yourString)
while ($match.Success) {
$resultlist.Add($match.Value) | out-null
$match = $match.NextMatch()
}
try this variant:
[regex]::Matches($data,'(?im)device #\d((?!\s*Device #\d)\r?\n.)*?') | select value
Value
-----
Device #0
Device #1
Device #2
Device #3
Device #4
While it doesn't exactly answer your question, I'll offer a slightly different approach:
($getdevice) -split '\s+(?=Device #\d)' | select -Skip 1
Just for fun,
$drives =
($getdevice) -split '\s+(?=Device #\d)' |
select -Skip 1 |
foreach { $Stringdata =
$_.replace(' : ','=') -replace 'Device #(\d)','Device = $1' -Replace 'Device is a (\w+)','DeviceIs = $1'
New-Object PSObject -Property $(ConvertFrom-StringData $Stringdata)
}
$drives | select Device,DeviceIs,'Total Size'
Device DeviceIs Total Size
------ -------- ----------
0 Hard drive 70007 MB
1 Hard drive 70007 MB
2 Hard drive 286102 MB
3 Hard drive 286102 MB
I used your sample data in a here-string for my testing. This should work although it can depend on where your sample data comes from.
Using powershell 3.0 I have the following
$getdevice |
select-string -pattern '(?smi)(Device\s#\d+?(.*?)*?(?=Device\s#|\Z))' -AllMatches |
ForEach-Object {$_.Matches} |
ForEach-Object {$_.Value}
or if your PowerShell Verison supports it...
($getdevice | select-string -pattern '(?smi)(Device\s#\d+?(.*?)*?(?=Device\s#|\Z))' -AllMatches).Matches.Value
Which returns 4 objects with their device id's. I don't know if you wanted those or not but the regex can be modified with lookarounds if you don't need those. I updated the regex to account for device id with more that one digit as well in case that happens.
The modifiers that I used
s
modifier: single line. Dot matches newline charactersm
modifier: multi-line. Causes ^ and $ to match the begin/end of each line (not only begin/end of string)i
modifier: insensitive. Case insensitive match (ignores case of [a-zA-Z])
Another regex pattern thats works in this way that is shorter
'(?smi)(Device\s#).*?(?=Device\s#|\Z)'