Регулярные выражения C# с символами \ Uxxxxxxxx в шаблоне

Regex.IsMatch( "foo", "[\U00010000-\U0010FFFF]" ) 

Выдает: System.ArgumentException: анализ диапазона «[-]» - [x-y] в обратном порядке.

Глядя на шестнадцатеричные значения для \ U00010000 и \ U0010FFF, я получаю: 0xd800 0xdc00 для первого символа и 0xdbff 0xdfff для второго.

Так что, наверное, у меня действительно есть одна проблема. Почему символы Юникода, образованные с помощью \ U, разделены на два символа в строке?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
0
11 318
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

Это суррогатные пары. Посмотрите на значения - они больше 65535. Символ - это всего лишь 16-битное значение. Как бы вы выразили 65536 всего лишь в 16 битах?

К сожалению, из документации не ясно, как (и справляется ли) механизм регулярных выражений в .NET с символами, которые не находятся в базовой многоязычной плоскости. (Шаблон \ uxxxx в документации по регулярным выражениям охватывает только 0-65535, точно так же, как \ uxxxx как escape-последовательность C#.)

Ваше реальное регулярное выражение больше или вы просто пытаетесь увидеть, есть ли в нем символы, отличные от BMP?

Собственно, ты прав. Из того, что я нашел, \ u поддерживает только 4 шестнадцатеричных цифры (ровно 4, не больше и не меньше), \ uFFFF - максимум. Я удалил свое «решение», потому что, хотя оно не вызывает ошибки, оно не похоже на правильное регулярное выражение Юникода. Я все еще считаю, что \ нужно избегать.

Michael Stum 12.12.2008 23:35

Без @ вам нужно было бы экранировать \ if \ UFFFF был синтаксисом регулярного выражения (например, \ d для [0-9]), но вместо этого это синтаксис строкового литерала (например, \ n для символа новой строки).

Christoph Rüegg 12.12.2008 23:40

Это прискорбно - многие современные смайлы попадают в эту категорию.

damian 18.01.2016 11:38

@damian: Вполне возможно, что за 7 лет, прошедших после этого поста, движок регулярных выражений стал лучше в этом отношении. Обратите внимание, что вопрос, на который я отвечал, касался только того, почему \Uxxxxxxxx заканчивается двумя символами ... часть "обработка регулярного выражения" несколько отделена. Возможно, вы захотите задать новый вопрос, если столкнетесь с этим в данный момент.

Jon Skeet 18.01.2016 12:07

12 лет с момента публикации, и это все еще не поддерживается.

gregsdennis 01.05.2020 12:26

@Jon Skeet

Итак, вы говорите мне, что нет способа использовать инструменты Regex в .net для сопоставления с символами за пределами диапазона utf-16?

Полное регулярное выражение:

^(\u0009|[\u0020-\u007E]|\u0085|[\u00A0-\uD7FF]|[\uE000-\uFFFD]|[\U00010000-\U0010FFFF])+$

Я пытаюсь проверить, содержит ли строка только то, что документ yaml определяет как печатные символы Unicode.

К сожалению, не знаю. Я не вижу в документации ничего о том, как использовать механизм регулярных выражений .NET с символами за пределами базовой многоязычной плоскости. Однако, вероятно, не так уж сложно реализовать то, что вы хотите, вообще без использования регулярных выражений.

Jon Skeet 12.12.2008 23:52

В качестве альтернативы вы можете использовать 16-битные кодовые точки, составляющие суррогатные пары: [\ ud800– \ udfff]. По крайней мере, это стоит попробовать ...

Jon Skeet 12.12.2008 23:54

(И в этот момент вы можете объединить несколько своих диапазонов вместе - более поздние биты просто [\ u00a0- \ ufffd].)

Jon Skeet 12.12.2008 23:54

Механизм регулярных выражений .NET работает с кодовыми точками UTF-16, а не с символами Unicode; см. code.logos.com/blog/2008/07/…. Я зарегистрировал ошибку Connect по этой проблеме: connect.microsoft.com/VisualStudio/feedback/…

Bradley Grainger 14.12.2008 03:55

Чтобы обойти такие вещи с помощью механизма регулярных выражений .Net, я использую следующий трюк: "[\U010000-\U10FFFF]" заменен на [\uD800-\uDBFF][\uDC00-\uDFFF] Идея заключается в том, что поскольку регулярные выражения .Net обрабатывают единицы кода, а не точки кода, мы предоставляем им суррогатные диапазоны как обычные символы. Также можно указать более узкие диапазоны, работая с краями, например: [\U011DEF-\U013E07] такой же, как (?:\uD807[\uDDEF-\uDFFF])|(?:[\uD808-\uD80E][\uDC00-\uDFFF])|(?:\uD80F[\uDC00-uDE07])

С ним труднее читать и работать, и он не такой гибкий, но все же подходит в качестве временного решения.

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