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

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

Броски: System.ArgumentException: анализ диапазона «[-]» - [xy] в обратном порядке.

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

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

12.12.2008 20:18:26
3 ОТВЕТА
РЕШЕНИЕ

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

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

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

10
12.12.2008 20:24:24
На самом деле, вы правы. Из того, что я обнаружил, \ u поддерживает только 4 шестнадцатеричных числа (ровно 4, не более, не менее), \ uFFFF - максимум. Я удалил свое «решение», потому что, хотя оно не приводит к ошибке, оно не является допустимым регулярным выражением Юникода. Я все еще верю, что \ нужно бежать.
Michael Stum♦ 12.12.2008 20:35:05
Без @ вам нужно было бы экранировать \, если бы \ UFFFF были синтаксисом регулярных выражений (например, \ d для [0-9]), но вместо этого это синтаксис строкового литерала (например, \ n для символа новой строки).
Christoph Rüegg 12.12.2008 20:40:52
Это прискорбно - многие современные эмодзи попадают в эту категорию.
damian 18.01.2016 08:38:51
@damian: Вполне возможно, что за 7 лет, прошедших с этого поста, движок регулярных выражений стал намного лучше в этом отношении. Заметьте, что вопрос, на который я отвечал, был только о том, почему в \Uxxxxxxxxитоге получается два символа ... часть "обработка регулярного выражения" несколько отделена. Возможно, вы захотите задать новый вопрос, если вы сталкиваетесь с этим в данный момент.
Jon Skeet 18.01.2016 09:07:36

@ Джон Скит

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

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

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

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

1
12.12.2008 20:47:42
Я не знаю, к сожалению. Я не вижу ничего в документации о том, как использовать механизм регулярных выражений .NET с символами вне базовой многоязычной плоскости. Однако, вероятно, не так уж сложно реализовать то, что вы хотите, без использования регулярных выражений вообще.
Jon Skeet 12.12.2008 20:52:53
В качестве альтернативы вы можете использовать 16-битные кодовые точки, которые составляют суррогатные пары: [\ ud800– \ udfff]. По крайней мере, стоит попробовать это ...
Jon Skeet 12.12.2008 20:54:17
(И в этот момент вы можете объединить несколько ваших диапазонов - более поздние биты просто [\ u00a0- \ ufffd].)
Jon Skeet 12.12.2008 20:54:53
Механизм регулярных выражений .NET работает с кодовыми точками UTF-16, а не с символами Unicode; см. code.logos.com/blog/2008/07/… . Я подал ошибку Connect по этой проблеме: connect.microsoft.com/VisualStudio/feedback/…
Bradley Grainger 14.12.2008 00:55:00

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

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

4
14.01.2013 20:33:19