根据任意文化设置将字符串转换为数字

时间:2015-11-09 19:18:10

标签: powershell

我需要对基于文化格式化的文本文件中的数字进行一些数学运算,所以我可以得到1,234.56或者我可以得到1.234,56甚至1 234,56。我最初想过用

来获得当前的文化
$culture = (Get-Culture).Name

然后将所有数字转换为en-US格式,进行数学运算,然后转换回原始格式。然而,这样简单的事情是行不通的。

$useCulture = New-Object System.Globalization.CultureInfo("en-US")

$value1 = "1,234.56"
$value2 = "1234,56"

[double]$value1 = $value1.ToString("f", $useCulture)
[double]$value2 = $value2.ToString("f", $useCulture)

$value1
$value2

对于这两个值,我希望得到1234.56,但第二个回到123456,所以显然我不明白ToString是如何工作的。我的猜测是它假定它采用en-US格式,因为这是我的机器配置的,然后它试图转换为相同的东西,而$ value2它只是假设千位分隔符在错了地方?在任何情况下,我将如何从任意格式转换为指定格式,以便我可以确定总和是正确的,然后转换回原始的任意格式? 或者,我完全错过了一些东西,有更好的方法来解决这个问题吗? 此外,如果可能的话,我希望能够使用PS 2.0来实现这一点,因为我不能依赖于升级到新版本的目标机器。

2 个答案:

答案 0 :(得分:0)

因此,如果整体结果是您想要只有数字且最多只有一个小数点的东西,我会尝试以下内容:

  • 用点
  • 替换任何非小数
  • 除去最后一个点之外的所有点,我们将其作为小数点

这是一个适用于少数测试用例的示例函数,但在测试中我绝对不是详尽无遗的:

function ConvertTo-Number {
  param(
    [Parameter(
      Mandatory=$true)]
      [System.String]
      $String
  )

  if($String -notmatch '\D'){
    return [int]$String
  } else {
    $ConvertedValue = ($String -replace '\D','.') -match '^(?<int>.*?)(?<dec>[\d]*)$'

    $ConvertedValue = $matches["int"] -replace '\D',''

    if($matches["dec"]){
      $ConvertedValue+=".$($matches["dec"])"
    }

    return [double]$ConvertedValue
  }
}

您可能希望首先清理输入字符串/如果可能,例如先删除空格。

答案 1 :(得分:0)

您可以执行以下操作:

# Your input value
$value = '1 234,56'

# Determine culture of input format
if ($value -match '\.\d\d$') {
    $culture = [cultureinfo]::GetCultureInfo('en-us')
} elseif ($value -match '\.\d\d\d') {
    $culture = [cultureinfo]::GetCultureInfo('de-de')
} elseif ($value -match ' \d\d\d|,\d\d$') {
    $culture = [cultureinfo]::GetCultureInfo('fr-fr')
}

# Parse input value into a double and perform math, e.g. value * 27.2
$newvalue = [double]::Parse($value,$culture) * 27.2

# Convert computed value back to original culture
$newvalue.ToString('n2',$culture)