为什么这个正则表达式返回真的?

时间:2012-03-20 21:00:31

标签: c# regex unicode globalization arabic

为什么这个正则表达式返回true?

Regex.IsMatch("العسكرية", "العسكري")

我用Google搜索,没有任何结果。

3 个答案:

答案 0 :(得分:7)

我怀疑你发布的内容实际上是反转的,其中较短的文本实际上是模式,较长的输入是匹配的输入。在这种情况下,这将返回true,因为模式匹配除了单词中的最后一个字母之外的所有内容。

为了澄清,العسكري是模式,العسكرية是输入。因为我知道阿拉伯语,我可以告诉你,后者确实是前者的部分匹配,所以如果值实际上是反转的话,结果将是真的。如果您引用this table of Arabic alphabets,则可以看到字母yā'(位于表格底部)是相同的字母。它的出现取决于它在一个单词中出现的位置。在前一个词中,它出现在最后,而后者则是倒数第二个字母。

当我从帖子中复制/粘贴时,值会反转,从而产生真正的值。为了更好地处理这个问题,我们可以将这些单词拆开以查看两种情况下的预期结果:

string first = "العسكري";
string second = "العسكرية";
Console.WriteLine(Regex.IsMatch(first, second)); // false
Console.WriteLine(Regex.IsMatch(second, first)); // true

答案 1 :(得分:2)

这是为散文而非代码设计的文本渲染规则的有趣结果。

上面写的方法调用中的第一个参数是“العسكرية”,右边是渲染(*)的参数。这个较长的参数是输入,左边渲染的较短子字符串实际上是模式,因此匹配。

(*:这假设您的浏览器知道如何进行从右到左的渲染。如果您将代码段粘贴到没有复杂文本布局支持的编辑器或控制台中,您将看到它真实的是......虽然阿拉伯语会被打破。)

诀窍是引号和逗号之类的标点字符是无方向的,因此可以根据周围环境从左到右或从右到左呈现。代码段的逻辑顺序是:

>>>>>>>>>>>>>>>
               <<<<<<<<<<<<<<<<<<<
                                  >>
Regex.IsMatch("العسكرية", "العسكري")

(其中有一个令人困惑的特性,即看起来围绕每个单独参数的引号实际上并非如此。)

这对于可读的混合语言的延伸具有某种可论证的意义,但却使代码非常混乱!你可以通过使用从左到右的方向性分解无方向角色来阻止它的发生:

Regex.IsMatch("العسكرية", /* foo */ "العسكري")

这在功能上与原始代码相同,但显示方式完全不同。在键入第一个拉丁字母时,您可以查看参数交换位置的位置。

答案 2 :(得分:1)

似乎Regex.IsMatch()告诉字符串中是否存在正则表达式,而不是整个字符串与正则表达式匹配(根据文档,它是“Indicates whether the specified regular expression finds a match in the specified input string.”)。第一个参数是输入,另一个是根据文档的模式,但在这里它似乎是另一种方式。最后一个(最左侧)字符在两个字符串中看起来像一个不同的字符,但这可能是因为连字的呈现方式。转储为UTF-8字节时,字符串为:

d8 a7 d9 84 d8 b9 d8 b3 d9 83 d8 b1 d9 8a

d8 a7 d9 84 d8 b9 d8 b3 d9 83 d8 b1 d9 8a d8 a9

所以第一个实际上是另一个的子串,它可以解释匹配(它确实要求参数顺序实际上与文档所说的相反)。