C# EndsWith 有时会给出错误的结果
C# EndsWith sometimes gives false results
"Cs".EndsWith("s") 和"cs".EndsWith("s") 给我“假”。
我整理了一个简单的控制台应用程序来展示问题:
string[] strings = { "s", "As", "Bs", "Cs", "Ds", "Es", "as", "bs", "cs", "ds", "es", "AAs", "ABs", "ACs", "ADs", "AEs" };
foreach (string str in strings)
Console.WriteLine(str + " ends with 's': " + str.EndsWith("s"));
Console.ReadKey();
结果是这样的:
s ends with 's': True
As ends with 's': True
Bs ends with 's': True
Cs ends with 's': False
Ds ends with 's': True
Es ends with 's': True
as ends with 's': True
bs ends with 's': True
cs ends with 's': False
ds ends with 's': True
es ends with 's': True
AAs ends with 's': True
ABs ends with 's': True
ACs ends with 's': False
ADs ends with 's': True
AEs ends with 's': True
我试过更改目标框架:(VS2013)
- 所有 4.x 版本都产生了这个错误
- 在 .NET 3.5、3.0、2.0 上运行良好。
也尝试使用 .NET 6.0 的 VS2022 预览版(在两台不同的计算机上),但产生了同样的问题。
在 dotnetfiddle (.NET 4.7.2) 中运行良好...:-O
你能帮我看看我应该在哪里寻找解决方案吗? (设置、安装的软件等)
提前致谢。
正如 Lasse V. Karlsen 所说,只有当 CultureInfo
设置为匈牙利语时才会出现此问题。要为您当前的程序解决这个问题,一个解决方案是将其设置为任何其他文化,例如 en-US
.
我在这里就是这么做的:
using System;
using System.Globalization;
using System.Threading;
public class Program
{
public static void Main()
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", false);
string[] strings = { "s", "As", "Bs", "Cs", "Ds", "Es", "as", "bs", "cs", "ds", "es", "AAs", "ABs", "ACs", "ADs", "AEs" };
foreach (string str in strings)
Console.WriteLine(str + " ends with 's': " + str.EndsWith("s"));
Console.ReadKey();
}
}
在此处运行:https://dotnetfiddle.net/PLEt8x
参考资料:here
一般情况下,最简单的方法是告诉字符串比较器它应该使用序号比较,如下所示:
str.EndsWith("s", StringComparison.Ordinal)
正如评论中的人已经解释的那样,大多数字符串函数都适用于当前的文化,而且这似乎是匈牙利语,这就是为什么你会得到这些结果。
另一个好处是,序号比较是迄今为止最快的。
正如其他人指出的那样,问题与匈牙利语中的组合字母有关。
https://en.wikipedia.org/wiki/Hungarian_alphabet
使用“StringComparison.Ordinal”参数解决了问题。
https://docs.microsoft.com/en-us/dotnet/api/system.string.endswith?view=net-5.0#System_String_EndsWith_System_String_System_StringComparison_
我制作了另一个小程序来测试其中的一些情况:
'''
var list = new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string,string>("cs", "s"),
new KeyValuePair<string,string>("dz", "z"),
new KeyValuePair<string,string>("dzs", "s"),
new KeyValuePair<string,string>("gy", "y"),
new KeyValuePair<string,string>("ly", "y"),
new KeyValuePair<string,string>("ny", "y"),
new KeyValuePair<string,string>("sz", "z"),
new KeyValuePair<string,string>("ssz", "z"),
new KeyValuePair<string,string>("ty", "y"),
new KeyValuePair<string,string>("zs", "s"),
new KeyValuePair<string,string>("Cs", "s"),
new KeyValuePair<string,string>("CS", "S"),
new KeyValuePair<string,string>("cS", "S"),
new KeyValuePair<string,string>("Dzs", "s"),
new KeyValuePair<string,string>("Dzs", "zs"),
new KeyValuePair<string,string>("Ty", "y"),
new KeyValuePair<string,string>("Ssz", "z"),
new KeyValuePair<string,string>("Ssz", "sz"),
};
Console.WriteLine("CultureInfo.CurrentCulture: " + CultureInfo.CurrentCulture);
foreach(var pair in list)
{
string sLetter = pair.Key;
string sEnd = pair.Value;
Console.WriteLine(sLetter + " ends with '" + sEnd + "': " + sLetter.EndsWith(sEnd) + "/" + sLetter.EndsWith(sEnd, StringComparison.Ordinal));
}
'''
结果如下:
'''
CultureInfo.CurrentCulture: hu-HU
cs ends with 's': False/True
dz ends with 'z': False/True
dzs ends with 's': False/True
gy ends with 'y': False/True
ly ends with 'y': False/True
ny ends with 'y': False/True
sz ends with 'z': False/True
ssz ends with 'z': False/True
ty ends with 'y': False/True
zs ends with 's': False/True
Cs ends with 's': False/True
CS ends with 'S': False/True
cS ends with 'S': True/True
Dzs ends with 's': False/True
Dzs ends with 'zs': False/True
Ty ends with 'y': False/True
Ssz ends with 'z': False/True
Ssz ends with 'sz': True/True
'''
感谢大家的帮助!
"Cs".EndsWith("s") 和"cs".EndsWith("s") 给我“假”。
我整理了一个简单的控制台应用程序来展示问题:
string[] strings = { "s", "As", "Bs", "Cs", "Ds", "Es", "as", "bs", "cs", "ds", "es", "AAs", "ABs", "ACs", "ADs", "AEs" };
foreach (string str in strings)
Console.WriteLine(str + " ends with 's': " + str.EndsWith("s"));
Console.ReadKey();
结果是这样的:
s ends with 's': True
As ends with 's': True
Bs ends with 's': True
Cs ends with 's': False
Ds ends with 's': True
Es ends with 's': True
as ends with 's': True
bs ends with 's': True
cs ends with 's': False
ds ends with 's': True
es ends with 's': True
AAs ends with 's': True
ABs ends with 's': True
ACs ends with 's': False
ADs ends with 's': True
AEs ends with 's': True
我试过更改目标框架:(VS2013)
- 所有 4.x 版本都产生了这个错误
- 在 .NET 3.5、3.0、2.0 上运行良好。
也尝试使用 .NET 6.0 的 VS2022 预览版(在两台不同的计算机上),但产生了同样的问题。
在 dotnetfiddle (.NET 4.7.2) 中运行良好...:-O
你能帮我看看我应该在哪里寻找解决方案吗? (设置、安装的软件等)
提前致谢。
正如 Lasse V. Karlsen 所说,只有当 CultureInfo
设置为匈牙利语时才会出现此问题。要为您当前的程序解决这个问题,一个解决方案是将其设置为任何其他文化,例如 en-US
.
我在这里就是这么做的:
using System;
using System.Globalization;
using System.Threading;
public class Program
{
public static void Main()
{
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US", false);
string[] strings = { "s", "As", "Bs", "Cs", "Ds", "Es", "as", "bs", "cs", "ds", "es", "AAs", "ABs", "ACs", "ADs", "AEs" };
foreach (string str in strings)
Console.WriteLine(str + " ends with 's': " + str.EndsWith("s"));
Console.ReadKey();
}
}
在此处运行:https://dotnetfiddle.net/PLEt8x
参考资料:here
一般情况下,最简单的方法是告诉字符串比较器它应该使用序号比较,如下所示:
str.EndsWith("s", StringComparison.Ordinal)
正如评论中的人已经解释的那样,大多数字符串函数都适用于当前的文化,而且这似乎是匈牙利语,这就是为什么你会得到这些结果。
另一个好处是,序号比较是迄今为止最快的。
正如其他人指出的那样,问题与匈牙利语中的组合字母有关。 https://en.wikipedia.org/wiki/Hungarian_alphabet
使用“StringComparison.Ordinal”参数解决了问题。 https://docs.microsoft.com/en-us/dotnet/api/system.string.endswith?view=net-5.0#System_String_EndsWith_System_String_System_StringComparison_
我制作了另一个小程序来测试其中的一些情况:
'''
var list = new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string,string>("cs", "s"),
new KeyValuePair<string,string>("dz", "z"),
new KeyValuePair<string,string>("dzs", "s"),
new KeyValuePair<string,string>("gy", "y"),
new KeyValuePair<string,string>("ly", "y"),
new KeyValuePair<string,string>("ny", "y"),
new KeyValuePair<string,string>("sz", "z"),
new KeyValuePair<string,string>("ssz", "z"),
new KeyValuePair<string,string>("ty", "y"),
new KeyValuePair<string,string>("zs", "s"),
new KeyValuePair<string,string>("Cs", "s"),
new KeyValuePair<string,string>("CS", "S"),
new KeyValuePair<string,string>("cS", "S"),
new KeyValuePair<string,string>("Dzs", "s"),
new KeyValuePair<string,string>("Dzs", "zs"),
new KeyValuePair<string,string>("Ty", "y"),
new KeyValuePair<string,string>("Ssz", "z"),
new KeyValuePair<string,string>("Ssz", "sz"),
};
Console.WriteLine("CultureInfo.CurrentCulture: " + CultureInfo.CurrentCulture);
foreach(var pair in list)
{
string sLetter = pair.Key;
string sEnd = pair.Value;
Console.WriteLine(sLetter + " ends with '" + sEnd + "': " + sLetter.EndsWith(sEnd) + "/" + sLetter.EndsWith(sEnd, StringComparison.Ordinal));
}
'''
结果如下: '''
CultureInfo.CurrentCulture: hu-HU
cs ends with 's': False/True
dz ends with 'z': False/True
dzs ends with 's': False/True
gy ends with 'y': False/True
ly ends with 'y': False/True
ny ends with 'y': False/True
sz ends with 'z': False/True
ssz ends with 'z': False/True
ty ends with 'y': False/True
zs ends with 's': False/True
Cs ends with 's': False/True
CS ends with 'S': False/True
cS ends with 'S': True/True
Dzs ends with 's': False/True
Dzs ends with 'zs': False/True
Ty ends with 'y': False/True
Ssz ends with 'z': False/True
Ssz ends with 'sz': True/True
'''
感谢大家的帮助!