SS != ss для сравнения с ICU без учета регистра

Следующий код C# возвращает false при использовании .NET 6, который использует библиотеку ICU для сравнения строк:

Thread.CurrentThread.CurrentCulture = new CultureInfo("de-de");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("de-de");
"ß".Equals("SS", StringComparison.CurrentCultureIgnoreCase);  // false with ICU

Насколько я понимаю, это должно быть правдой на основе правил складывания регистра Юникода (а также, что более важно, стандартных немецких орфографических правил):

00DF; F; 0073 0073; # LATIN SMALL LETTER SHARP S (CaseFolding.txt)

При использовании устаревшей реализации Microsoft NLS приведенный выше код возвращает true.

Так почему же библиотека ICU, используемая .NET 6, отличается от стандарта Unicode или мое понимание стандарта здесь неверно?

Оригинальный вопрос C#, который привел к этому.

Это заявление. В чем здесь вопрос?

Fildor 23.04.2024 11:17

@Fildor «Насколько я понимаю, это должно быть правдой, исходя из правил свертывания регистра в Юникоде», но я могу сделать это немного яснее, чтобы избежать недоразумений.

Voo 23.04.2024 11:20

Непонятно, какой ответ вы хотите получить от такого вопроса «почему». Это лучше подходит для отчета об ошибке для отделения интенсивной терапии, чем для вопроса о переполнении стека.

Sweeper 23.04.2024 11:23

.NET 6 не использует специальную реализацию ICU. Само отделение интенсивной терапии ведет себя по-другому. В документах указано, что ß должно соответствовать ss в поиске и регулярном выражении, но ничего не говорится о равенстве.

Panagiotis Kanavos 23.04.2024 11:25

@Sweeper Предполагается, что это ошибка, а не неправильное понимание спецификации с моей стороны. Ответ вполне может быть таким: «Параграф X последней спецификации говорит, что это приемлемое поведение».

Voo 23.04.2024 11:27

Баг это или нет, особого значения не имеет. Многие заявки решаются словами «не проблема», «преднамеренно» и тому подобное. Я хочу сказать, что вы, скорее всего, получите лучшие ответы, отправив отчет об ошибке, а не публикуя вопрос о переполнении стека.

Sweeper 23.04.2024 11:31

@Sweeper, это правильный вопрос, затрагивающий довольно много людей. И согласно документации по поиску строк ICU, "Heisse".Contains("ß") должно работать. Немецкие правила были созданы не вчера, и немецкий рынок не является второстепенным. Когда Microsoft раньше говорила о «локализованности», она имела в виду только французский, немецкий и испанский языки. Это может быть ошибка или может потребоваться другое кодирование.

Panagiotis Kanavos 23.04.2024 11:34

Фактически, в документах явно упоминается pattern “ß” will find occurrences of “ss” or “ß”. в качестве примера.

Panagiotis Kanavos 23.04.2024 11:38

Итак, я понимаю это как «это ошибка или я что-то упускаю»… Я действительно думаю, что и Свипер, и Панайотис правы. С одной стороны, было бы полезно получить ответ на соответствующим образом сформулированный отчет об ошибке, с другой стороны, было бы хорошо, если бы у кого-нибудь (в SO) уже был ответ и практическое решение - ошибка или нет.

Fildor 23.04.2024 11:50

Например, если я ищу ß на этой странице, он также соответствует всем экземплярам SS (в Edge).

Matthew Watson 23.04.2024 11:57

^^ Как ни странно, этого нет в Firefox на немецкой Windows 10.

Fildor 23.04.2024 12:00

Это... еще страннее

Matthew Watson 23.04.2024 12:05

Совпадения на Chrome, Brave,...

Fildor 23.04.2024 12:13

Инструмент тестирования отделения интенсивной терапии также сравнивает их, как и ожидалось. Такое ощущение, что библиотека ICU работает правильно, но что-то не так/отсутствует/непонятно при ее использовании в рамках.

Ralf 23.04.2024 12:13

@Ralf Это отличный инструмент, добавил его в закладки для будущего использования. Итак, теперь, когда я понял проблему, кажется, что отчет об ошибках для Microsoft готов. Посмотрим, что они скажут.

Voo 23.04.2024 13:18

Я создал проблему с репозиторием dotnet теперь, когда мы, вероятно, изолировали проблему. Посмотрим, что из этого получится.

Voo 23.04.2024 14:07
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
12
16
245
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Юникод — это сложно.

Оказывается, такое поведение намеренное. См. этот выпуск Github по этому вопросу, где Тарекх резюмирует проблему:

При сортировке ICU используется так называемая сила сортировки. Сила может быть первичной, вторичной, третичной или четвертичной. Мы пытаясь сопоставить как можно больше вариантов сравнения .NET с одним из эти силы. которые работают нормально, за исключением таких особых случаев. К сожалению, ICU make ß равен ss только при наличии мощности ICU. является первичным. Мы не можем переключиться на эту силу по умолчанию в .NET. потому что это сломает много других вещей.

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

Обходной путь заключается в использовании StringComparer.Create(CultureInfo.CurrentCulture, CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase) - CompareOptions.IgnoreNonSpace заставляет первичную силу сопоставления, и в этом случае ß и ss будут сравниваться равными.

Вероятно, этот переход приведет к некоторым непредвиденным побочным эффектам, но, по крайней мере, немецкоязычные будут счастливы.

Проголосовал за, сохранил и добавил в закладки. Самые ценные вопросы и ответы. Если бы можно было +2.

Fildor 24.04.2024 08:23

Как показывает этот ответ, сравнение основано на весах сопоставления, а не на строках с регистром. Различия по случаям в УЦА происходят на третичном уровне. Разница между ß и ss возникает не при третичной прочности, а скорее при вторичной прочности, согласно соответствующим стандартам DIN. Таким образом, нечувствительность к регистру, которая увеличивает силу сортировки с третичного на вторичный, не повлияет на разницу между весами сортировки ß и ss.

Andj 28.04.2024 02:23

Другие вопросы по теме