While 基思·希尔的有用回答 https://stackoverflow.com/a/2380257/45375向您展示如何按需更改脚本的当前区域性(从 PSv3+ 和 .NET Framework v4.6+ 开始,更现代的替代方案:
[cultureinfo]::CurrentCulture = [cultureinfo]::InvariantCulture
), 有no需要改变文化,因为 - 正如您在对问题的第二次更新中发现的 -PowerShell 的字符串插值法- 而不是使用-f
运算符 - 始终使用不变的而不是current culture:
换句话说:
如果你更换'val: {0}' -f 1.2
with "val: $(1.2)"
, 数字字面量1.2
is not根据当前文化的规则进行格式化。
您可以通过运行 (在一条线上; PSv3+、.NET 框架 v4.6+):
PS> [cultureinfo]::currentculture = 'de-DE'; 'val: {0}' -f 1.2; "val: $(1.2)"
val: 1,2 # -f operator: GERMAN culture applies, where ',' is the decimal mark
val: 1.2 # string interpolation: INVARIANT culture applies, where '.' is the decimal mark.
注:在PowerShell(核心)7+,对不同文化的改变在会议的剩余时间内仍然有效(正如它应该为Windows PowerShell也是,但没有)。
背景:
By design,[1] but perhaps surprisingly, PowerShell applies the invariant rather than the current culture in the following string-related contexts, if the type at hand supports culture-specific conversion to and from strings:
正如中所解释的这个深入的答案 https://stackoverflow.com/a/30542422/45375, PowerShell 明确请求文化不变加工,如果可能的话- 通过通过[cultureinfo]::InvariantCulture https://learn.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo.invariantculture实例 - 在以下场景中(PowerShell 执行的字符串化相当于调用.psobject.ToString([NullString]::Value, [cultureinfo]::InvariantCulture)
值):
-
When 字符串插值:如果对象的类型实现了IFormattable
界面。
-
When casting:
-
to一个字符串, 包括implicit转换 when 绑定到一个[string]
- 类型化参数:如果源类型实现了[IFormattable] https://learn.microsoft.com/en-us/dotnet/api/system.iformattable界面。
-
from一个字符串:如果目标类型是静态的.Parse()
方法有一个重载[IFormatProvider] https://learn.microsoft.com/en-US/dotnet/api/System.IFormatProvider- 类型化参数(这是一个由[cultureinfo] https://learn.microsoft.com/en-US/dotnet/api/System.Globalization.CultureInfo).
-
When 字符串比较 (-eq
, -lt
, -gt
) , 用一个String.Compare()超载 https://learn.microsoft.com/en-us/dotnet/api/system.string.compare接受一个CultureInfo
范围。
-
Others?
请注意,单独地,custom字符串化应用于以下 .NET 类型的强制转换/隐式字符串化:
As for 的目的不变的文化 https://learn.microsoft.com/en-us/dotnet/api/system.globalization.cultureinfo.invariantculture:
不变文化是文化不敏感的;这是与英语相关,但与任何国家/地区无关.
[...]
与文化敏感数据不同,文化敏感数据可能会因用户自定义或 .NET Framework 或操作系统的更新而发生更改,而不变的文化数据是随着时间的推移和跨文化的稳定并且不能由用户定制。这使得不变区域性对于需要区域性独立结果的操作特别有用,例如保留格式化数据的格式化和解析操作,或者要求数据以固定顺序显示而不管区域性的排序和排序操作。
据推测,正是跨文化的稳定性促使 PowerShell 的设计者在以下情况下始终如一地使用不变的文化:隐含地与字符串之间的转换.
例如,如果您硬编码日期字符串,例如'7/21/2017'
到一个脚本中,然后尝试将其转换为日期[date]
强制转换,PowerShell 的文化不变行为可确保脚本在美国英语以外的文化生效时运行时不会中断 -幸运的是,不变文化还可以识别 ISO 8601 格式的日期和时间字符串;
e.g., [datetime] '2017-07-21'
也有效。
另一方面,如果您确实想转换为current-适合文化的字符串,你必须这样做明确地.
总结一下:
-
转换to strings:
- 在内部嵌入具有文化敏感的默认字符串表示形式的数据类型实例
"..."
产生一种文化——不变的代表([double]
or [datetime]
是此类类型的示例)。
-
为了得到一个current-文化代表、召唤
.ToString()
明确或使用-f https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_Operators#format-operator--f),格式化运算符(可能在内部"..."
通过一个封闭的$(...)
).
-
转换from strings:
文化不变的例子:
文化敏感的例子:
在以下情况下,当前文化受到尊重:
-
With -f
,字符串格式化运算符(如上所述):
-
[cultureinfo]::currentculture = 'de-DE'; '{0}' -f 1.2
yields 1,2
- Pitfall: Due to operator precedence https://msdn.microsoft.com/powershell/reference/5.1/Microsoft.PowerShell.Core/about/about_Operator_Precedence, any expression as the RHS of
-f
must be enclosed in (...)
in order to be recognized as such:
- E.g.,
'{0}' -f 1/10
被评估为好像('{0}' -f 1) / 10
已被指定;
use '{0}' -f (1/10)
反而。
-
Default输出到控制台:
-
e.g., [cultureinfo]::CurrentCulture = 'de-DE'; 1.2
yields 1,2
-
这同样适用于 cmdlet 的输出;例如。,
[cultureinfo]::CurrentCulture = 'de-DE'; Get-Date '2017-01-01'
yields
Sonntag, 1. Januar 2017 00:00:00
-
Caveat:在某些情况下,作为不受约束的参数传递到脚本块的文字可能会导致区域性不变的默认输出 - 请参阅GitHub 问题 #4557 https://github.com/PowerShell/PowerShell/issues/4557 and GitHub 问题 #4558 https://github.com/PowerShell/PowerShell/issues/4558.
-
在所有?)cmdlets:
-
那些表现的平等比较:
-
Select-Object https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/select-object与
-Unique
转变;还请注意 - 异常 - 情况 -敏感的执行比较,并且从 PowerShell 7.2.4 开始,不区分大小写甚至不能作为选择加入 - 请参阅GitHub 问题 #12059 https://github.com/PowerShell/PowerShell/issues/12059.
- Select-Object https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/select-object
- Compare-Object https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/compare-object
- Others?
-
那些写入文件:
-
Set-Content https://learn.microsoft.com/powershell/module/microsoft.powershell.management/set-content and Add-Content https://learn.microsoft.com/powershell/module/microsoft.powershell.management/add-content
-
Out-File https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/out-file and therefore its virtual alias,
>
(and >>
)
- e.g.,
[cultureinfo]::CurrentCulture = 'de-DE'; 1.2 > tmp.txt; Get-Content tmp.txt
yields 1,2
-
由于.NET的逻辑,当使用静态::Parse()
/ ::TryParse()
数字类型的方法,例如[double] https://learn.microsoft.com/en-us/dotnet/api/system.double.parse?view=netframework-4.7.1#System_Double_Parse_System_String_仅传递要解析的字符串;例如,与文化fr-FR
实际上(其中,
是小数点),[double]::Parse('1,2')
返回双倍1.2
(i.e., 1 + 2/10
).
-
Caveat: As bviktor https://stackoverflow.com/users/1708230/bviktor points out, thousands separators are recognized by default, but in a very loose fashion: effectively, the thousands separator can be placed anywhere inside the integer portion, irrespective of how many digits are in the resulting groups, and a leading
0
is also accepted; e.g., in the en-US
culture (where ,
is the thousands separator), [double]::Parse('0,18')
perhaps surprisingly succeeds and yields 18
.
- 要抑制对千位分隔符的识别,请使用类似
[double]::Parse('0,18', 'Float')
,通过NumberStyles范围 https://learn.microsoft.com/en-us/dotnet/api/system.globalization.numberstyles?view=netframework-4.7.1
-
无心的文化敏感性不会被纠正以保持向后兼容性:
-
在编译的参数绑定类型转换中cmdlets (but PowerShell代码- 脚本或函数 -is文化不变) - 参见GitHub 问题 #6989 https://github.com/PowerShell/PowerShell/issues/6989.
-
In the
-as
操作员 - see GitHub 问题 #8129 https://github.com/PowerShell/PowerShell/issues/8129.
-
In
[hashtable]
关键查找 - see 这个答案 https://stackoverflow.com/a/53324566/45375 and GitHub 问题 #8280 https://github.com/PowerShell/PowerShell/issues/8280.
-
[在 v7.1+ 中修复] 在 LHS 中
-replace
运营 - see GitHub 问题 #10948 https://github.com/PowerShell/PowerShell/issues/10948.
-
Others?
[1] The aim is to support programmatic processing using representations that do not vary by culture and do not change over time. See the linked quote from the docs later in the answer.