New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Large hiragana and small hiragana in Japanese are treated as the same letter. #20786
Comments
In Japanese hiragana, there are two types of letters: the larger ones, These are different characters and pronounced differently. Example:
In Windows PowerShell 5.1, these were correctly treated as different letters. But they are treated as the same in versions newer than PowerShell Core (I first discovered this phenomenon in PowerShell 7.1.0). PS> "あ" -eq "ぁ"
True
PS> "あ" -ceq "ぁ"
False Each of This phenomenon also occurs when unicode codepoints are used to specify characters. PS> "`u{3041}"
ぁ
PS> "`u{3042}"
あ
PS> "`u{3041}" -eq "`u{3042}"
True
PS> "`u{3041}" -ceq "`u{3042}"
False On the other hand, Katakana-letters seems to be treated correctly: Unicode Table
|
PowerShell is just the messenger here, I think this comes down to a change in localization libraries that was introduced in .NET 5 (at the time of PowerShell 7.1), namely the move from NLS to ICU. In many contexts, PowerShell uses the invariant culture for string operations, which means that: "あ" -eq "ぁ" is effectively the same as: [string]::Equals("あ", "ぁ", 'InvariantCultureIgnoreCase') And in .NET 5+ / PowerShell 7.1+, this now yields The linked help topic discusses an opt-in to the old (.NET Framework) behavior based on the Windows-only NLS APIs, but note that in PowerShell it will invariably apply session-wide. Note that # -> $false in .NET 5+ / PowerShell 7.1+ too
[char] 'あ' -eq [char] 'ぁ' The reason is that with |
If you want case sensitive comparison use -ceq instead of -eq (and you can write -ieq to be explicit that you are using case insensitive). |
@mklement0 Thanks for the reply! I found the following in the link.
Is there any way to opt out of ICU and back to NLS from # inside $profile
$env:DOTNET_SYSTEM_GLOBALIZATION_USENLS = 1 I also tried setting Is this something that has to do with .NET and can't be configured from PowerShell? |
@AWtnb, the You can define a persistent environment variable, but note that this means that all future sessions - whether or not profile loading is disabled with E.g., for the current user (a one-time action): [Environment]::SetEnvironmentVariable('DOTNET_SYSTEM_GLOBALIZATION_USENLS', '1', 'User') |
@mklement0 It is too much work to type Update-TypeData -TypeName "System.String" -Force -MemberType ScriptMethod -MemberName ExactlyEquals -Value {
param([string]$s)
return [string]::Equals($this, $s, [System.StringComparison]::Ordinal)
} (Prompt is customized in |
Oops, the above custom method would be the same as using For the original purpose: Update-TypeData -TypeName "System.String" -Force -MemberType ScriptMethod -MemberName CaseInSensitiveEquals -Value {
param([string]$s)
return [string]::Equals($this, $s, [System.StringComparison]::OrdinalIgnoreCase)
} |
Yes, I forgot to mention that setting the As an aside: Your first attempt at defining |
I learned a lot! Thank you very much. |
Prerequisites
Steps to reproduce
Expected behavior
Actual behavior
Error details
No response
Environment data
Visuals
The text was updated successfully, but these errors were encountered: