了解 CultureInvariant 和 IgnoreCase 在 [A-Za-z] 上的后果
本文关键字:后果 A-Za-z CultureInvariant IgnoreCase 了解 | 更新日期: 2023-09-27 18:32:39
如果我基于以下模式创建一个Regex
:@"[A-Za-z]+"
,如果我已经在使用RegOptions.CultureInvariant
,它匹配的集合是否会通过添加RegOptions.IgnoreCase
而改变(由于这样的问题(? 我认为这是一个明显的"不,这只是多余和重复的"。 在我的测试中,这就是我所展示的,但我想知道我是否由于确认偏见而错过了一些东西。
如果我在这一点上错了,请纠正我,但我相信我肯定需要使用CultureInvariant
,因为我也不知道文化会是什么。 MSDN 参考
注意:这不是我需要使用的实际模式,只是其中最简单的关键部分。 完整的模式是:@"[A-Za-z0-9's!''#$(),.:;=@''-{}|/&]+"
,以防在符号、大小写和文化周围确实存在一些奇怪的行为。 不,我没有创建模式,我只是在消费它,无法更改它,我意识到在/&
之前不需要|
。
如果我能改变模式...
- 具有
CultureInvariant
和IgnoreCase
的模式"[a-z]"
在功能上等同于仅使用"[A-Za-z]"
CultureInvariant
对吗? - 假设#1是正确的,哪个会更有效,为什么? 我猜较短的模式评估更有效,但我不知道内部现在如何工作,以充满信心地说出来。
使用此程序,我们可以测试所有可能的双字母序列:
static void Main()
{
var defaultRegexOptions = RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture | RegexOptions.Singleline;
var regex1 = new Regex(@"^[A-Za-z]+$", defaultRegexOptions);
var regex2 = new Regex(@"^[A-Za-z]+$", defaultRegexOptions | RegexOptions.IgnoreCase);
ParallelEnumerable.Range(char.MinValue, char.MaxValue - char.MinValue + 1)
.ForAll(firstCharAsInt =>
{
var buffer = new char[2];
buffer[0] = (char)firstCharAsInt;
for (int i = char.MinValue; i <= char.MaxValue; i++)
{
buffer[1] = (char)i;
var str = new string(buffer);
if (regex1.IsMatch(str) != regex2.IsMatch(str))
Console.WriteLine("dfjkgnearjkgh");
}
});
}
较长的序列可能会有所不同,但我认为这不太可能。这是没有区别的有力证据。
该程序需要 20 分钟才能运行。
不幸的是,这个答案并没有提供任何关于为什么会这样的见解。
所以我对这一切的运作方式有一个根本性的误解。 我想这就是让我失望的原因...
Regex regex = new Regex("[A-Za-z]", RegexOptions.IgnoreCase);
。将返回false
regex.IsMatch("ı")
,但true
regex.IsMatch("İ")
。 如果我删除IgnoreCase
它为两者返回false
,如果我使用CultureInvariant
(带或不带IgnoreCase
(,无论如何它都会返回false
,这基本上归结为斯科特张伯伦在他的评论中所说的。 谢谢斯科特。
最终,我希望"İ"和"ı"都被拒绝,而我只是在考虑CultureInvariant
之前就通过IgnoreCase
加入而让自己都改变了。 如果我删除IgnoreCase
并添加CultureInvariant
那么我可以保持模式不变,并使其与我想要的相匹配。
如果我能够将模式更改为仅"[A-Z]"
那么我可以使用两个标志并且仍然可以获得所需的行为。 但是关于改变模式,哪个更有效的那一点只是好奇心。 我不想讨论讨论中可能出现的所有问题,以及我可以改变模式的所有方法。 我关心的是文化、不区分大小写和这两个RegexOptions
。
总而言之,我需要放弃IgnoreCase
然后围绕文化的整个问题就消失了。 如果模式是a-z
或A-Z
,并且我需要使用IgnoreCase
来匹配上下,那么我也需要使用CultureInvariant
。