Почему это регулярное выражение возвращает истину? - PullRequest
4 голосов
/ 21 марта 2012

Почему это регулярное выражение возвращает true?

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

Я погуглил, и ничего не пришло.

Ответы [ 3 ]

7 голосов
/ 21 марта 2012

Я подозреваю, что то, что вы опубликовали, на самом деле перевернуто, где более короткий текст на самом деле является шаблоном, а более длинный ввод сопоставляется с вводом. В этом случае это вернет true, поскольку шаблон соответствует всему, кроме последней буквы в слове.

Для пояснения, العسكري - это шаблон, а العسكرية - это вход. Так как я знаю арабский язык, я могу сказать вам, что последний действительно будет частичным совпадением первого, поэтому результат будет истинным, если значения будут на самом деле обратными. Если вы обратитесь к этой таблице арабских алфавитов , вы увидите, что буква yā ’ (внизу таблицы) - это та же самая рассматриваемая буква. Его появление зависит от того, где это происходит в слове. В первом слове оно появляется в конце, а во втором - второе-последнее письмо.

Когда я копирую / вставляю из вашего поста, значения меняются местами, в результате чего получается истинное значение. Чтобы работать с этим лучше, мы можем разделить слова на части, чтобы увидеть ожидаемые результаты в обоих сценариях:

string first = "العسكري";
string second = "العسكرية";
Console.WriteLine(Regex.IsMatch(first, second)); // false
Console.WriteLine(Regex.IsMatch(second, first)); // true
2 голосов
/ 23 марта 2012

Это интересный результат правил рендеринга текста, предназначенных для прозы, а не кода.

Первый аргумент в вызове вашего метода, как написано выше, это "العسكرية", аргумент, который отображается (*) вПравая сторона.Этот более длинный аргумент является входным параметром, а более короткая подстрока, отображаемая слева, на самом деле является шаблоном, следовательно, соответствует.

(*: это предполагает, что ваш браузер знает, как выполнять рендеринг справа налево.Если вы вставите фрагмент кода в редактор или консоль, в которой нет поддержки сложного текстового макета, вы увидите, какой она есть на самом деле ... хотя арабский язык тогда будет разбит.)

Хитрость заключается в том, что знаки пунктуации, такие как кавычки и запятая, не имеют направления, поэтому могут отображаться слева направо или справа налево в зависимости от их окружения.Логический порядок фрагмента:

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

(который имеет еще одно запутанное свойство, заключающееся в том, что кавычки, которые появляются вокруг каждого отдельного параметра, на самом деле не являются.)

Это делаетнекоторый спорный смысл для участков читаемого смешанного языка, но делает код очень запутанным!Вы можете остановить это, разбив ряд бессмысленных символов на нечто, имеющее направленность слева направо:

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

Функционально это тот же код, что и оригинал, но он отображается совершенно по-другому.При вводе первой буквы латинского алфавита вы можете наблюдать за позициями мест замены аргументов.

1 голос
/ 21 марта 2012

Кажется, что Regex.IsMatch() сообщает, есть ли в строке регулярное выражение, а не соответствует ли вся строка регулярному выражению (в соответствии с документацией, оно " Указывает, находит ли указанное регулярное выражение совпадениев указанной входной строке.").Первый аргумент - это ввод, другой - шаблон согласно документам, но здесь, похоже, все наоборот.Последний (самый левый) символ выглядит как другой в двух строках, но это, вероятно, из-за способа визуализации лигатур.При выводе в виде байтов 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

, поэтому первая на самом деле является подстрокой другой, которая объясняет совпадение (для этого требуетсядля того, чтобы порядок аргументов действительно был обращен к тому, что написано в документации).

...