Solved

Powershell Regex

Posted on 2013-06-06
8
358 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
  • 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 68

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 39

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
 
LVL 68

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
Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

 
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 39

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 74

Expert Comment

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

Open in new window

0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Suggested Solutions

Hi all.   The other day I had to change the passwords for a bunch of users on the fly. Because they were so many, I decided to do it in an automated way and I would like to share it with you all.   If you are not doing it directly in a Domain Co…
This article will help you understand what HashTables are and how to use them in PowerShell.
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…
Explain concepts important to validation of email addresses with regular expressions. Applies to most languages/tools that uses regular expressions. Consider email address RFCs: Look at HTML5 form input element (with type=email) regex pattern: T…

707 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now