首页 > 其他分享 >记一次系统迁移遇到的中文字符串排序问题

记一次系统迁移遇到的中文字符串排序问题

时间:2023-01-30 08:33:48浏览次数:66  
标签:Sort 中文 Console list System item WriteLine 字符串 排序

背景

不久前,迁移了一个 framework 项目到 .net core 上面,部署也从 Windows 的 IIS 到 linux 的容器化。

期间遇到了一个关于中文字符串排序的问题,在这里记录一下。

复现与处理

下面这段代码就是出现问题的代码。

var list = new List<string>
{ 
    "阿莫西林", "阿司匹林", "阿卡波糖"
};

list.Sort();

foreach (var item in list)
{
    Console.WriteLine(item);
}

大家觉得,排序后的结果会是怎么样的呢?

这个排序结果取决于当前环境的 CultureInfo,因为 list.Sort() 最后会调用 Array.Sort<T>(Array keys, Array? items, int index, int length, IComparer? comparer),没有显式的传递 comparer 参数,这个时候就会用到 Comparer.Default,这个 default 的构造函数就传入了 CultureInfo.CurrentCulture

大体调用逻辑可以参考下面的 github 链接

https://github.com/dotnet/runtime/blob/dfe1076090adad6990747e6abed8bf6699371877/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs#L1046
https://github.com/dotnet/runtime/blob/dfe1076090adad6990747e6abed8bf6699371877/src/libraries/System.Private.CoreLib/src/System/Array.cs#L1817
https://github.com/dotnet/runtime/blob/dfe1076090adad6990747e6abed8bf6699371877/src/libraries/System.Private.CoreLib/src/System/Array.cs#L1850
https://github.com/dotnet/runtime/blob/dfe1076090adad6990747e6abed8bf6699371877/src/libraries/System.Private.CoreLib/src/System/Collections/Comparer.cs#L21

知道这个的话,就可以来验证一下了。

Console.WriteLine("Sort by default culture , {0}", Thread.CurrentThread.CurrentCulture.Name);
list.Sort();

foreach (var item in list)
{
    Console.WriteLine(item);
}

Console.WriteLine("");

Console.WriteLine("Sort by culture , en-US");
list.Sort(StringComparer.Create(new System.Globalization.CultureInfo("en-US"), true));
foreach (var item in list)
{
    Console.WriteLine(item);
}
Console.WriteLine("");

Console.WriteLine("Sort by culture , zh-Hans-CN");
list.Sort(StringComparer.Create(new System.Globalization.CultureInfo("zh-Hans-CN"), true));
foreach (var item in list)
{
    Console.WriteLine(item);
}
Console.WriteLine("");

Console.WriteLine($"CurrentCulture Name = {System.Globalization.CultureInfo.CurrentCulture.Name}"); 

本地调试输出如下:

基于 mcr.microsoft.com/dotnet/runtime:6.0-bullseye-slim 镜像,

docker build -t sort:v1 -f .\Dockerfile .
docker run --rm sort:v1

放到容器下面输出如下:

可以看到,默认的是为空的,也就是没有任何指定。

由于 bullseye-slim 镜像已经包含了 icu 相关的库,所以可以直接指定 LC_ALL 或 LANG 为 zh_CN 即可。

docker run --rm -e LC_ALL=zh_CN sort:v1
# 或
docker run --rm -e LANG=zh_CN sort:v1

这个时候的输出就是和本地调试一致的了。

所以最后的解决方案是 添加多一个环境变量 来解决这个问题。

如果是用 alpine 镜像的话,要注意安装 icu 相关的库。

参考资料

标签:Sort,中文,Console,list,System,item,WriteLine,字符串,排序
From: https://www.cnblogs.com/catcher1994/p/17074249.html

相关文章

  • Redis的设计与实现(1)-SDS简单动态字符串
    现在在高铁上,赶着春节回家过年,无座站票,电脑只能放行李架上,面对着行李架撸键盘--看过<Redis的设计与实现>这本书,突然想起,便整理下SDS的内容,相对后面的章节,......
  • 字符串1 最基础的字符串算法
    Trie很简单的东西,这里就不阐述了。constintN=400005+111;structTrie{intnxt[N][27],cnt;intvis[N];voidinit(){memset(nxt,0,siz......
  • Pandas字符串离散化处理
    字符串离散化处理importpandasaspdimportnumpyasnpfrommatplotlibimportpyplotasplt#读取csv文件file_path="./IMDB-Movie-Data.csv"df=pd.read_csv......
  • 远程控制软件 TeamViewer 4.0.5459 简体中文版
    优点:没什么说的。亮点:支持直接拖放文件或目录到被控机器屏幕(目录),这个好!缺点:被控制的目标机器被锁定后无法使用屏幕连接访问,郁闷。。。啊下载地址:​​​http://vbcoder.qupan......
  • js 把字符串转成json对象的三种方法
    转自:js将字符串转换成json的三种方式不管字符串是否含有转义字符,都能转换成Json对象1,js自带的eval函数,其中需要添加小括号eval('('+str+')');functionstrToJson(st......
  • 插入排序
    话不多少,直接上代码(Coding):/***插入排序对于少量元素来说选择排序是一种有效的最简单的排序算法*算法和冒泡排序有点像都是逐一比较插入一个元素然后取出元素......
  • (AtCoder Beginner Contest 287)(D 字符串前后缀合并匹配)(E Trie求最长公共前缀(LCP)
    D-MatchorNot(字符串前后缀合并匹配)题目大意:给定两个字符串S和T,对于每个x=0,1,2...|T|求S的子串(前x个字符和后|T|-x个字符在不改变顺序的情况下组成)是否与T相......
  • 选择排序
    话不多说,直接上代码(Coding):/***选择排序每轮选择当前位置找出后面的较小值与当前位置进行替换*/publicclassDemo03{publicstaticvoidmain(String[]ar......
  • 【3】Python基础数据类型之字符串,切片,列表,元组,字典
    1.创建字符串  2.字符串输入输出,使用input()接收用户输入,使用print()输出。  3.字符串的索引下标4.切片:指对操作的对象截取其中一部分的操作。字符串、列表、元......
  • 【Matlab学习1.7】字符串处理
    字符串的表示在Matlab中,字符串是用单引号括起来的字符序列。例1.7.1:>>xm='MatlabUniversity'xm='MatlabUniversity'>>xm(1:3)ans='Mat'若字符串......