Powershell - 正则表达式多重匹配

Fra*_*tar 5 regex powershell regex-group powershell-4.0

也许我的推理是错误的,但我不能让这个工作.

这是我的正则表达式: (Device\s#\d(\n.*)*?(?=\n\s*Device\s#|\Z))

试试看:http://regex101.com/r/jQ6uC8/6

$getdevice是输入字符串.我从命令行工具的Stream/Output中获取此字符串.

$dstate = $getdevice |
     select-string -pattern '(Device\s#\d(\n.*)*?(?=\n\s*SSD\s+|\Z))' -AllMatches |
     % { $_ -match '(Device\s#\d(\n.*)*?(?=\n\s*SSD\s+|\Z))' > $null; $matches[0] }
Write-Host $dstate
Run Code Online (Sandbox Code Playgroud)

输出:

设备#0设备#1设备#2设备#3设备#4

$ matches [1]的输出相同,$ matches [2]为空.

有没有办法可以获得所有比赛,比如regex101.com?我正在尝试将输出/字符串拆分为单独的变量(一个用于Device0,一个用于Device1,Device2,依此类推).

更新:这是命令行工具的输出:http://pastebin.com/BaywGtFE

Mat*_*att 10

我在here-string中使用了您的示例数据进行测试.这应该有效,尽管它可以取决于您的样本数据来自何处.

使用PowerShell 3.0我有以下内容

$getdevice | 
    select-string -pattern '(?smi)(Device\s#\d+?(.*?)*?(?=Device\s#|\Z))' -AllMatches | 
    ForEach-Object {$_.Matches} | 
    ForEach-Object {$_.Value}
Run Code Online (Sandbox Code Playgroud)

或者如果你的PowerShell Verison支持它......

($getdevice | select-string -pattern '(?smi)(Device\s#\d+?(.*?)*?(?=Device\s#|\Z))' -AllMatches).Matches.Value
Run Code Online (Sandbox Code Playgroud)

返回带有设备ID的4个对象.我不知道你是否想要那些,但如果你不需要那些正则表达式可以用外观进行修改.我更新了正则表达式,以便在发生这种情况时更多地考虑设备ID.

我使用的修饰符

  1. s修饰符:单行.Dot匹配换行符
  2. m修饰符:多行.导致^和$匹配每行的开头/结尾(不仅是字符串的开头/结尾)
  3. i修饰符:不敏感.不区分大小写的匹配(忽略[a-zA-Z]的情况)

另一种以这种方式工作的正则表达式模式更短

'(?smi)(Device\s#).*?(?=Device\s#|\Z)'
Run Code Online (Sandbox Code Playgroud)


zx8*_*x81 6

使用您现有的正则表达式,要获取字符串中所有匹配项的列表,请使用以下选项之一:

选项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
} 
Run Code Online (Sandbox Code Playgroud)

选项 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()
} 
Run Code Online (Sandbox Code Playgroud)