也许我的推理是错误的,但我无法解决这个问题。
这是我的正则表达式:(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
输出:
设备#0设备#1设备#2设备#3设备#4
$ matches [1]的输出相同,$ matches [2]为空。
有没有办法可以获得所有比赛,比如regex101.com?我试图将输出/字符串拆分为单独的变量(一个用于Device0,一个用于Device1,Device2,等等)。
更新:以下是命令行工具的输出:http://pastebin.com/BaywGtFE
答案 0 :(得分:9)
我在here-string中使用了您的示例数据进行测试。这应该有效,尽管它可以取决于您的样本数据来自何处。
使用PowerShell 3.0我有以下
$getdevice |
select-string -pattern '(?smi)(Device\s#\d+?(.*?)*?(?=Device\s#|\Z))' -AllMatches |
ForEach-Object {$_.Matches} |
ForEach-Object {$_.Value}
或者您的PowerShell Verison支持它......
($getdevice | select-string -pattern '(?smi)(Device\s#\d+?(.*?)*?(?=Device\s#|\Z))' -AllMatches).Matches.Value
返回带有设备ID的4个对象。我不知道你是否想要那些,但如果你不需要那些正则表达式可以用外观进行修改。我更新了正则表达式,以便在发生这种情况时更多地考虑设备ID。
我使用的修饰符
s
修饰符:单行。 Dot匹配换行符m
修饰符:多行。导致^和$匹配每行的开头/结尾(不是 只开始/结束字符串)- 醇>
i
修饰符:不敏感。不区分大小写的匹配(忽略[a-zA-Z]的情况)
另一种以这种方式工作的正则表达式模式
'(?smi)(Device\s#).*?(?=Device\s#|\Z)'
答案 1 :(得分:2)
使用现有的正则表达式,要获取字符串中所有匹配项的列表,请使用以下选项之一:
选项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
}
选项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()
}
答案 2 :(得分:2)
虽然它没有完全回答你的问题,但我会提供一种稍微不同的方法:
($getdevice) -split '\s+(?=Device #\d)' | select -Skip 1
只是为了好玩,
$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
答案 3 :(得分:1)
试试这个变种:
[regex]::Matches($data,'(?im)device #\d((?!\s*Device #\d)\r?\n.)*?') | select value
Value
-----
Device #0
Device #1
Device #2
Device #3
Device #4