Regex соответствует египетским иероглифам

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

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

Итак, кто-нибудь может сообщить мне диапазон Unicode для этих символов.

Ответ 1

TLDNR: \p{Egyptian_Hieroglyphs}

Javascript

Egyptian_Hieroglyphs принадлежат к астральной плоскости, которая использует более 16 бит для кодирования символа. Javascript, начиная с ES5, не поддерживает астральные плоскости (подробнее об этом), поэтому вы должны использовать суррогатные пары. Первый суррогат

U+13000 = d80c dc00

последний

U+1342E = d80d dc2e

что дает

re = /(\uD80C[\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E])+/g

t = document.getElementById("pyramid").innerHTML
document.write("<h1>Found</h1>" + t.match(re))
<div id="pyramid">

  some     𓀀	really    𓀁	old    𓐬	stuff    𓐭	    𓐮
  
  </div>

Ответ 2

Unicode кодирует египетские иероглифы в диапазоне от U + 13000 - U + 1342F (за пределами базовой многоязычной плоскости).

В этом случае существует два способа записи регулярного выражения:

  • Задав диапазон символов от U + 13000 - U + 1342F.

    При указании диапазона символов в регулярном выражении для символов в BMP так же просто, как [a-z], в зависимости от поддержки языка, сделать это для символов в астральных плоскостях может быть не так просто.

  • Указав блок Unicode для египетских иероглифов

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

Java

(В настоящее время я не знаю, как другая реализация библиотек классов Java обрабатывает символы астральной плоскости в классах Pattern).

Внедрение Sun/Oracle

Я не уверен, имеет ли смысл говорить о совпадении символов в астральных плоскостях в Java 1.4, поскольку поддержка символов за пределами BMP была добавлена ​​только в Java 5 путем переоснащения существующей реализации String (которая использует UCS-2 для своих внутреннее строковое представление) с помощью методов, ориентированных на код.

Так как Java продолжает разрешать одиночные суррогаты (которые не могут образовать пару с другим суррогатом), которые должны быть указаны в String, это приводило к беспорядку, поскольку суррогаты не являются настоящими символами, а одиночные суррогаты недействительны в UTF-16.

Pattern класс увидел крупный капитальный ремонт от Java 1.4.x до Java 5, поскольку класс был переписан, чтобы обеспечить поддержку соответствия символов Юникода в астральных плоскостях: строка шаблона преобразуется в массив кодовой точки до того, как она анализируется, а входная строка перемещается с помощью методов, ориентированных на код, в классе String.

Вы можете больше узнать о безумии в Java regex в этом ответе tchist.

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

Java 5 (и выше)

"[\uD80C\uDC00-\uD80D\uDC2F]"

Java 7 (и выше)

"[\\uD80C\\uDC00-\\uD80D\\uDC2F]"
"[\\x{13000}-\\x{1342F}]"

Поскольку мы сопоставляем любую кодовую точку, принадлежащую блоку Unicode, ее также можно записать в виде:

"\\p{InEgyptian_Hieroglyphs}"
"\\p{InEgyptian Hieroglyphs}"
"\\p{InEgyptianHieroglyphs}"

"\\p{block=EgyptianHieroglyphs}"
"\\p{blk=Egyptian Hieroglyphs}"

Поддерживаемый Java \p синтаксис для блока Unicode с 1.4, но поддержка египетского блока иероглифов была добавлена ​​только в Java 7.

PCRE (используется в PHP)

Пример PHP уже описан в georg answer:

'~\p{Egyptian_Hieroglyphs}~u'

Обратите внимание, что флаг u является обязательным, если вы хотите совместить точки кода вместо соответствия блоками кода.

Не уверен, что есть лучший пост в StackOverflow, но Я написал некоторое объяснение о влиянии флага u (режим UTF) в этом ответе моей.

Следует отметить, что Egyptian_Hieroglyphs доступен только из PCRE 8.02 (или версии не раньше PCRE 7.90).

В качестве альтернативы вы можете указать диапазон символов с синтаксисом \x{h...hh}:

'~[\x{13000}-\x{1342F}]~u'

Обратите внимание на обязательный флаг u.

Синтаксис \x{h...hh} поддерживается как минимум PCRE 4.50.

JavaScript (ECMAScript)

ES5

Метод диапазона символов (который является единственным способом сделать это в ванильном JavaScript) уже включен в georg answer. Регулярное выражение немного модифицировано для охвата всего блока, включая зарезервированную неназначенную кодовую точку.

/(?:\uD80C[\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2F])/

В приведенном выше решении демонстрируется техника, которая соответствует диапазону символов в астральной плоскости, а также ограничениям JavaScript RegExp.

JavaScript также страдает от той же проблемы строкового представления, что и Java. Хотя Java действительно исправило класс Pattern в Java 5, чтобы позволить ему работать с кодовыми точками, JavaScript RegExp все еще застревает во времена UCS-2, заставляя нас работать с блоками кода вместо кодовой точки в регулярном выражении.

ES6

Это скоро изменится. Если все будет хорошо, есть вероятность, что поддержка сопоставления кодовых точек будет добавлена ​​в ECMAScript 6, который доступен с помощью флага u, чтобы предотвратить нарушение существующих реализаций в предыдущих версиях ECMAScript.

Отметьте Поддержка из второй ссылки выше для списка браузера, предоставляющего экспериментальную поддержку ES6 RegExp.

С введением синтаксиса \u{h...hh} в ES6 диапазон символов можно переписать аналогично Java 7:

/[\u{13000}-\u{1342F}]/u

Или вы также можете напрямую указать символ в литерале RegExp, хотя намерение не так четко разрезано, как [a-z]:

/[𓀀-𓐯]/u

Обратите внимание на модификатор u в обоих регулярных выражениях выше.

Все еще застрял с ES5? Не беспокойтесь, вы можете перевести ES6 Unicode RegExp на ES5 RegExp с regxpu.