Powershell - Regular Expression Multiple Matches

后端 未结 4 2077
庸人自扰
庸人自扰 2020-12-17 21:57

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://

相关标签:
4条回答
  • 2020-12-17 22:33

    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()
    } 
    
    0 讨论(0)
  • 2020-12-17 22:34

    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
    
    0 讨论(0)
  • 2020-12-17 22:42

    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                
    
    0 讨论(0)
  • 2020-12-17 22:56

    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

    1. s modifier: single line. Dot matches newline characters
    2. m modifier: multi-line. Causes ^ and $ to match the begin/end of each line (not only begin/end of string)
    3. 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)'
    
    0 讨论(0)
提交回复
热议问题