给出字符串
RAM Statistics: 5954 / 8174 743=InUse 746=Peak
我需要一个RegEx(或三个)来提取743
,746
,理想情况下5954 / 8174
,以便每个都可以分配给特定变量。
我认为这就是LookBehind的用途,但我有一段时间实际上得到一个RegEx到#34;获取一个空格和= Peak"之间的数字,例如。
我试过了
$string = 'RAM Statistics: 5954 / 8174 743=InUse 746=Peak'
$regexPeak = '(?<= )(.#)(?=\=Peak)'
$string -match $regexPeak > $null
$peak = $matches[0]
Write-Host "$peak"
但那并没有回归。
更新: 按约书亚我试过
$string = 'RAM Statistics: 5954 / 8174 743=InUse 746=Peak'
$regexPeak = '(\d+) / (\d+) (\d+)=\D+(\d+)=peak/gi'
$string -match $regexPeak
$peak = $matches[0]
Write-Host "$peak!"
$ matches [0]和[1]都返回= Peak之前的所有内容。所以
Statistics: 5954 / 8174 743=InUse 746!
答案 0 :(得分:2)
$Pattern = '(\d+) *\/ *(\d+) +(\d+)=[^0-9]*(\d+)'
$string = 'RAM Statistics: 5954 / 8174 743=InUse 746=Peak'
if ($string -match $Pattern){$Matches[0..4]}
5954 / 8174 743=InUse 746
5954
8174
743
746
答案 1 :(得分:1)
只是拆开试用代码:
$string = 'RAM Statistics: 5954 / 8174 743=InUse 746=Peak'
$regexPeak = '(?<= )(.#)(?=\=Peak)'
你的正则表达式有一个空间的后视,这是好的。然后它有一个中间位,其分组为(.#)
,几乎可以肯定不是你想要的 - 一个点匹配任何一个字符,一个哈希匹配一个哈希。因此它会匹配4#
,z#
,##
而非746
之类的内容。然后你有一个积极的前瞻,看起来不错。但综合效果是将内部位锁定为两个字符并查找space, two characters (where the second is a hash), equals peak
。
您可能希望\d
表示数字,+
表示&#34; 匹配一次或多次&#34;,{{1} }
你要做的第二件事是混合外观和分组。正则表达式的一个用途是将\d+
之类的字符串与'number is 4'
之类的模式进行匹配。整个模式匹配并显示在输出中,然后查询捕获组以从整个匹配中挑选出'number is (\d)'
。 4
为$matches[0]
,number is 4
为$matches[1]
。
正则表达式的另一个用途是将数字与像4
之类的后瞻匹配,因为后视匹配但它不会出现在输出中。因此(?<=number is )\d
的输出只是$matches[0]
,您不需要任何组。所以你在没有输出中的文本的情况下使用lookarounds进行匹配,并尝试对数字进行分组,这样可行,但是它过度/不必要地混合使用了两种不同的方法。
这意味着你的正则表达式非常接近于工作:
4
和
$regexPeak = '(?<= )(.#)(?=\=Peak)' # change to
$regexPeak = '(?<= )\d+(?=\=Peak)' # to indicate "one or more digits"
答案 2 :(得分:0)
更新了正则表达式:
/(\d+) \/ (\d+) (\d+)=\D+(\d+)=peak/gi
答案 3 :(得分:0)
其他方法,没有正则表达式
$template=@"
{Data:RAM Statistics:{RamStat: 123456 / 123} {InUseValue:743}=InUse {PeakValue:746}=Peak}
"@
$string = 'RAM Statistics: 5954 / 8174 743=InUse 746=Peak'
$result=$string | ConvertFrom-String -TemplateContent $Template
write-host "RamStat : " $result.Data.RamStat
write-host "PeakValue : " $result.Data.PeakValue
write-host "InUseValue : " $result.Data.InUseValue
答案 4 :(得分:0)
另一个答案是更复杂的RegEx与命名组一起工作regex101.com但是脚本失败了。我想由于RegEx实现的差异。
$string = @'
RAM Statistics: 1954 / 8174 743=InUse 746=Peak
RAM Statistics: 2954 / 8174 746=Peak
RAM Statistics: 3954 / 8174 743=InUse
RAM Statistics: 4954 / 8174
'@
$Pattern = '(?sm)^RAM Statistics: *(?<Ram>\d+) *\/ *(?<Ratio>\d+)( *(?<InUse>\d+)=InUse)?( *(?<Peak>\d+)=Peak)?'
$string.split('`n') |ForEach{
$_ -match $Pattern|out-null
"RAM {0}/{1} {2} InUse {3} Peak" -f $Matches.Ram,$Matches.Ratio,$Matches.InUse,$Matches.Peak
}
RAM 1954/8174 InUse Peak
RAM 2954/8174 InUse 746 Peak
RAM 4954/8174 InUse Peak
答案 5 :(得分:0)
好的,这里略有不同的方法,使用RegEx对象而不是-match
运算符。由于你提到了不一致,我已经运行了两次,一次是添加了垃圾文本和额外的空格,一次只有一些项目存在。
$MyRegEx = ([regex]'\b(?<peak>\d+)(?=\=Peak)|(?<ratio>\d+\s*\/\s*\d+)|\b(?<inuse>\d+)(?=\=InUse)')
$String='RAM Statistics: 5954 / 8174 1=somegarbage 743=InUse 746=Peak'
$Results=$MyRegex.matches($String)
Switch($Results){
{$_.groups['ratio'].success}{"Ratio = " + $_.Groups['ratio'].value}
{$_.groups['inuse'].success}{"InUse = " + $_.Groups['inuse'].value}
{$_.groups['peak'].success}{"Peak = " + $_.Groups['peak'].value}
}
$String2 = 'RAM Statistics: 5954 / 8174 746=Peak'
$Results=$MyRegex.matches($String2)
Switch($Results){
{$_.groups['ratio'].success}{"Ratio = " + $_.Groups['ratio'].value}
{$_.groups['inuse'].success}{"InUse = " + $_.Groups['inuse'].value}
{$_.groups['peak'].success}{"Peak = " + $_.Groups['peak'].value}
}
这会得到你的结果:
Ratio = 5954 / 8174
InUse = 743
Peak = 746
和第二个字符串:
Ratio = 5954 / 8174
Peak = 746
这是通过使用命名捕获组完成的,然后评估结果,查看该捕获组是否在特定分组中成功。我用Switch
完成了这项工作。
答案 6 :(得分:0)
[regex]::Matches('RAM Statistics: 5954 / 8174 743=InUse 746=Peak','\D+(\d+)')|%{$_.groups[1].value}
它给出了下一个结果::
5954
8174
743
746