获取指定字符串之前的数字

时间:2017-03-31 16:35:02

标签: regex powershell

给出字符串

RAM Statistics: 5954 / 8174 743=InUse 746=Peak

我需要一个RegEx(或三个)来提取743746,理想情况下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!

7 个答案:

答案 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