正如标题所说,为什么会发生这种情况?
PS C:\temp> "zzz" -le "~~~"
False
PS C:\temp> "~~~" -le "zzz"
True
"〜"是最后一个ASCII字符的下一个。我无法理解它之前的整理情况" z"。
答案 0 :(得分:6)
这是因为~
(代字号)是变音符号,默认比较是语言比较,而不是序数。语法比较在排序时忽略变音符号。所有这些都是Unicode的结果。
尝试:
PS C:\> $x = @('aaa','~~~','zzz')
PS C:\> [System.Array]::Sort($x)
PS C:\> $x
~~~
aaa
zzz
PS C:\> [System.Array]::Sort($x,[System.StringComparer]::Ordinal)
PS C:\> $x
aaa
zzz
~~~
C#中的类似答案是here。
这里使用en-US
文化与一些具有变音符号的字符串进行了较大的比较:
PS C:\> $x = @("0","9","a","A","á","Á","ab","aB","Ab","áb","Áb","Æ","z","Z","~")
PS C:\> [Array]::Sort($x)
PS C:\> $x
~
0
9
a
A
á
Á
ab
aB
Ab
áb
Áb
Æ
z
Z
PS C:\> [Array]::Sort($x,[StringComparer]::Ordinal)
PS C:\> $x
0
9
A
Ab
Z
a
aB
ab
z
~
Á
Áb
Æ
á
áb
那么,哪个是正确的?它将取决于您的应用程序,但.Net Framework默认基于文化的比较。
据我所知,字符串比较默认为[System.StringComparer]::CurrentCulture
表示区分大小写,[System.StringComparer]::CurrentCultureIgnoreCase
表示不区分大小写。我不知道如何直接改变这一点。即使使用不变的文化似乎也不会影响事物:
PS C:\> [System.Threading.Thread]::CurrentThread.CurrentCulture = [System.Globalization.CultureInfo]::InvariantCulture
PS C:\> [System.Array]::Sort($x)
PS C:\> $x
~~~
aaa
zzz
PS C:\> $x[0] -le $x[1]
True
强制进行有序比较,use System.String.CompareOrdinal:
[System.String]::CompareOrdinal($StringA,$StringB)
如果结果为否定,则$StringA
小于$StringB
如果结果为零,则$StringA
等于$StringB
如果结果是正确的,则$StringA
大于$StringB
。
因此,这个:
'zzz' -le '~~~'
等同于序数比较:
PS C:\> [System.String]::CompareOrdinal('zzz','~~~') -le 0
True
答案 1 :(得分:5)
简短的回答是:because it uses [String]::Compare()
并返回相同的结果。
答案越长:它不是ASCII值比较。它取决于文化信息和比较选项,默认情况下使用Word排序。
比较使用当前的文化来获得特定文化 套管规则和字母顺序等信息 个性人物。例如,文化可以指定 某些字符组合被视为单个字符, 或者以特定方式比较大写和小写字符, 或者字符的排序顺序取决于字符 在它之前或之后。
使用单词排序规则进行比较。更多 有关单词,字符串和序数排序的信息,请参阅 System.Globalization.CompareOptions
[string]::Compare('z','~')
# 1
[string]::Compare('~','z')
# -1
[string]::Compare('z','~',[cultureinfo]::CurrentCulture,[System.Globalization.CompareOptions]::Ordinal)
# -4
[string]::Compare('~','z',[cultureinfo]::CurrentCulture,[System.Globalization.CompareOptions]::Ordinal)
# 4