Solved

Powershell Regex

Posted on 2013-06-06
8
365 Views
Last Modified: 2013-07-17
I need to extract a number from a string in Powershell. I will have a variable defined which contains text similar to this:

<VolumeInfo><VolumeInfoItem Name="F:" OriginalAccessPath="F:" State="14" HResult="0" DetailedHResult="0" PreviousState="9" IsCritical="0" IsIncremental="1" BlockLevel="0" HasFiles="1" 
HasSystemState="0" IsCompacted="0" IsPruned="0" IsRecreateVhd="0" FullBackupReason="0" DataTransferred="189367997" NumUnreadableBytes="0" TotalSize="189367997" TotalNoOfFiles="31" 
Flags="84" BackupTypeDetermined="1" SSBTotalNoOfFiles="0" SSBTotalSizeOnDisk="0" /></VolumeInfo>

Open in new window


I need to extract the number from DataTransferred="nnnnnnnnn" to a separate variable.
The number will vary in length.
I would prefer to use
$OutputString = select-string $Inputstring -InputObject $string1 -pattern "regex here"

Open in new window


What would my regex be?
0
Comment
Question by:VSI-O
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +1
8 Comments
 
LVL 40

Assisted Solution

by:Subsun
Subsun earned 375 total points
ID: 39227947
Try...
$String = '<VolumeInfo><VolumeInfoItem Name="F:" OriginalAccessPath="F:" State="14" HResult="0" DetailedHResult="0" PreviousState="9" IsCritical="0" IsIncremental="1" BlockLevel="0" HasFiles="1" 
HasSystemState="0" IsCompacted="0" IsPruned="0" IsRecreateVhd="0" FullBackupReason="0" DataTransferred="189367997" NumUnreadableBytes="0" TotalSize="189367997" TotalNoOfFiles="31" 
Flags="84" BackupTypeDetermined="1" SSBTotalNoOfFiles="0" SSBTotalSizeOnDisk="0" /></VolumeInfo>'

$OutputString = select-string -InputObject $string -pattern 'DataTransferred="\d+"' | %{($_.Matches -split '"')[1]}

$OutputString

Open in new window

0
 
LVL 70

Assisted Solution

by:Qlemo
Qlemo earned 125 total points
ID: 39228225
I would use XML parsing instead - more straight-forward:
$xml = [xml] '<VolumeInfo><VolumeInfoItem Name="F:" OriginalAccessPath="F:" State="14" HResult="0" DetailedHResult="0" PreviousState="9" IsCritical="0" IsIncremental="1" BlockLevel="0" HasFiles="1" 
HasSystemState="0" IsCompacted="0" IsPruned="0" IsRecreateVhd="0" FullBackupReason="0" DataTransferred="189367997" NumUnreadableBytes="0" TotalSize="189367997" TotalNoOfFiles="31" 
Flags="84" BackupTypeDetermined="1" SSBTotalNoOfFiles="0" SSBTotalSizeOnDisk="0" /></VolumeInfo>'

$DataTransferred = $xml.VolumeInfo.VolumeInfoItem.DataTransferred

Open in new window

0
 
LVL 40

Expert Comment

by:footech
ID: 39228376
@Qlemo - Nice catch on the XML format.  I'll have to remember to keep an eye out for that.

@Subsun - How did you figure out the "...| %{($_.Matches -split '"')[1]}" syntax, specifically that the split would work at that point?  To get to a value I've always done something like "...| %{$_.Matches} | %{$_.Value}" (after which I could do a split, etc.).
0
Has Powershell sent you back into the Stone Age?

If managing Active Directory using Windows Powershell® is making you feel like you stepped back in time, you are not alone.  For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why.

 
LVL 70

Expert Comment

by:Qlemo
ID: 39228539
Looking detailed for the regex, I'll rather use this, which also can cope with an array of strings:
$String = '<VolumeInfo><VolumeInfoItem Name="F:" OriginalAccessPath="F:" State="14" HResult="0" DetailedHResult="0" PreviousState="9" IsCritical="0" IsIncremental="1" BlockLevel="0" HasFiles="1" 
HasSystemState="0" IsCompacted="0" IsPruned="0" IsRecreateVhd="0" FullBackupReason="0" DataTransferred="189367997" NumUnreadableBytes="0" TotalSize="189367997" TotalNoOfFiles="31" 
Flags="84" BackupTypeDetermined="1" SSBTotalNoOfFiles="0" SSBTotalSizeOnDisk="0" /></VolumeInfo>'

$DataTransferred = $string | % {if ($_  -match '\w*DataTransferred="(\d+)".*') {$matches[1]}} 

Open in new window

0
 
LVL 40

Assisted Solution

by:Subsun
Subsun earned 375 total points
ID: 39230851
@footech, I had used it in many of my codes, that's why I know it works.. :-) ...  If you're looking for a technical explanation... I think, by default -split accepts the Matches value property (captured substring from the input string) and process it.. But I could not find any reference to justify the reason.. If I find something I will post it here.. or may be Dr Qlemo can explain about it..

Other options which I can think of to get the same result is..
$OutputString = If ($string -match 'DataTransferred="(\d+)"') {$matches[1]}

Open in new window

or
[regex]$regex = 'DataTransferred="(\d+)"'
$OutputString = $regex.Matches($String) | % {$_.Groups[1].Value}

Open in new window

0
 
LVL 40

Expert Comment

by:footech
ID: 39231106
@Subsun - I've no doubt that it works, it's just that I'd never seen -split used directly on a RegEx Match object, and was surprised to see it given that the Match object isn't a string.  Maybe it works because Value is the only property of a Match object that is a string, so perhaps if an object is passed to the split operator it works on any properties that are strings.

Here's another variation (essentially just different syntax for your last)
$OutputString = [regex]::match($string,'DataTransferred="(\d+)"') | %{$_.groups[1].value}

Open in new window

0
 
LVL 40

Accepted Solution

by:
Subsun earned 375 total points
ID: 39231165
Still not sure how -Split decide which property to take and process.. I have seen different behavior on different objects..

Here is some examples..


> $Test = Get-Service VSS | Select Status
> $Test.Status.gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     ServiceControllerStatus                  System.Enum
> $Test -split "="
@{Status
Stopped}


> $Test = Get-Service VSS | Select Status,Dis*
> $Test.Displayname.gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object
> $Test -split "="
@{Status
Stopped; DisplayName
Volume Shadow Copy}

> $Test = Get-Service | Select -First 2
> $Test

Status   Name               DisplayName
------   ----               -----------
Running  !SASCORE           SAS Core Service
Stopped  AdobeFlashPlaye... Adobe Flash Player Update Service

here it decide to take the name property and process it..
> $Test -split "Play"
!SASCORE
AdobeFlash
erUpdateSvc

> $Test = Get-Process | Select -First 2
> $Test

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    131       5     2476       4736    59            1828 atieclxx
    120       4     1840       2988    24            1360 atiesrxx

> $Test[0].processname.gettype()
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     String                                   System.Object

> $Test -Split "\."
System
Diagnostics
Process (atieclxx)
System
Diagnostics
Process (atiesrxx)
0
 
LVL 75

Expert Comment

by:käµfm³d 👽
ID: 39232484
Try:
-pattern "(?<=DataTransferred=`")\d+"

Open in new window

0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

The Nano Server Image Builder helps you create a custom Nano Server image and bootable USB media with the aid of a graphical interface. Based on the inputs you provide, it generates images for deployment and creates reusable PowerShell scripts that …
A quick Powershell script I wrote to find old program installations and check versions of a specific file across the network.
Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an antispam), the admini…

696 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question