Barry Chum
Barry Chum

Reputation: 859

Powershell string to number functions?

I am looking for an easy way to convert numeric strings e.g. "1.78M" "1.47B" to an integer variable.

Any help is appreciated.

thanks

Upvotes: 1

Views: 2626

Answers (2)

latkin
latkin

Reputation: 16812

There is nothing built in that supports suffixes like M for million, B for billion, etc. There is only built-in support for "file size" suffixes, for example 32KB -> 32768

Here's my attempt at a basic script version to address your problem. This supports multi-character suffixes if needed, or no suffix at all. It will always return an [int], so be wary of overflow (e.g. 5.5B will cause an error since it won't fit in an int). You can modify the types a bit to support bigger numbers.

function ToNumber
{
   param([string] $NumberString)

   # add other multiplier suffixes to this table
   $multipliers = @{ 'B' = 1000000000; 'M' = 1000000; 'K' = 1000; '' = 1 }

   switch -regex ($numberString)
   {
      '^(?<base>[\d\.]+)(?<suffix>\w*)$'
      {
         $base = [double] $matches['base']
         $multiplier = [int] $multipliers[$matches['suffix']]

         if($multiplier)
         {
            [int]($base * $multiplier)
         }
         else
         {
            throw "$($matches['suffix']) is an unknown suffix"
         }
      }
      default
      {
         throw 'Unable to parse input'
      }
   }
}

C:\> ToNumber '1.7B'
1700000000
C:\> ToNumber '1.7K'
1700

Upvotes: 1

Keith Hill
Keith Hill

Reputation: 202002

Are you looking for M == MB or M == 1E6? If it is the former, PowerShell understands KB, MB, GB and TB e.g.:

C:\PS> Invoke-Expression "2MB"
2097152

Big caveat here with Invoke-Expression, if you're getting the string from a user, file, i.e. an untrusted source. You have to be careful about executing it. Say the string is "2MB; Remove-Item C:\ -Recurse -Force -Whatif -EA 0", you'd have a bad day using Invoke-Expression on that string. BTW, I'm being nice here by adding the -Whatif. :-)

If it is the latter, you could do a regex -replace followed by a coercion e.g.:

C:\PS> [long]("3.34 B" -replace '(\d+)\s*(B)','$1E9')
3340000000

Upvotes: 3

Related Questions