std.uni
Модуль std.uni предоставляет реализацию основных алгоритмов и структур данных Юникода. Он не включает в себя примитивы кодирования и декодирования UTF, см. std.utf.decode и std.utf.encode в std.utf для этой функциональности.
| Категория | Функции |
|---|---|
| Декодирование | byCodePoint byGrapheme decodeGrapheme graphemeStride |
| Сравнение | icmp sicmp |
| Классификация | isAlpha isAlphaNum isCodepointSet isControl isFormat isGraphical isIntegralPair isMark isNonCharacter isNumber isPrivateUse isPunctuation isSpace isSurrogate isSurrogateHi isSurrogateLo isSymbol isWhite |
| Нормализация | NFC NFD NFKD NormalizationForm normalize |
| Разложение | decompose decomposeHangul UnicodeDecomposition |
| Составление | compose composeJamo |
| Множества | CodepointInterval CodepointSet InversionList unicode |
| Дерево префиксного поиска | codepointSetTrie CodepointSetTrie codepointTrie CodepointTrie toTrie toDelegate |
| Регистр | asCapitalized asLowerCase asUpperCase isLower isUpper toLower toLowerInPlace toUpper toUpperInPlace |
| Utf8Matcher | isUtfMatcher MatcherConcept utfMatcher |
| Разделители | lineSep nelSep paraSep |
| Основные блоки | allowedIn combiningClass Grapheme |
Все перечисленные примитивы работают с символами Юникода и наборами символов. Для функций, которые работают с символами ASCII и игнорируют Юникод символы, см. std.ascii. Для определений Юникода символа, кодовой точки и других терминов, используемых в данном модуле, см. раздел терминология ниже.
Основное внимание в данном модуле уделяется основным потребностям разработки приложений, учитывающих Юникод. В этой связи он предоставляет следующие оптимизированные примитивы:
- Классификация символов по категории и общим свойствам:
isAlpha,isWhiteи другие. - Регистронезависимое сравнение строк (
sicmp,icmp). - Преобразование текста в любой из четырёх форм нормализации с помощью
normalize. - Декодирование (
decodeGrapheme) и итерация (byGrapheme,graphemeStride) по воспринимаемым пользователем символам, то есть по кластерамGrapheme. - Разложение и составление отдельных символов в соответствии с каноническими или правилами совместимости, см.
composeиdecompose, включая специальный вариант для слогов ХангулcomposeJamoиdecomposeHangul.
Признается, что приложение может потребовать дополнительных усовершенствований и расширений, таких как менее известные алгоритмы или адаптация существующих алгоритмов для региональных потребностей. Чтобы помочь пользователям в создании дополнительной функциональности помимо основных примитивов, модуль предоставляет:
CodepointSet, тип для удобной работы с наборами символов. Помимо обычной алгебры множеств, он предоставляет необычную функцию: генератор кода на D для обнаружения кодовых точек в этом наборе. Это полезно для метапрограммируемых парсерных фреймворков и используется во внутреннем функционале для классификации в небольших наборах, например,isWhite.- Способ создания оптимальных упакованных таблиц с несколькими этапами, также известных как специальный случай Trie. Функции
codepointTrie,codepointSetTrieсоздают пользовательские деревья, которые сопоставляют dchar со значением. Результатом является быстрый и предсказуемый поиск Ο(1), который используется в функциях, таких какisAlphaиcombiningClass, но для наборов данных, определённых пользователем. - Полезный приём для приложений с поддержкой Юникода, которые выполняют классификацию символов закодированных кодовых точек: избегать ненужного декодирования во что бы то ни стало.
utfMatcherобеспечивает улучшение по сравнению с обычным потоком декодировать-классифицировать-обрабатывать, объединяя декодирование и классификацию. Выделяя необходимые биты непосредственно из закодированных единиц кода, обработчики достигают значительных улучшений производительности. См.MatcherConceptдля общего интерфейса обработчиков UTF. - В целом полезные строительные блоки для пользовательской нормализации:
combiningClassдля запроса класса объединения иallowedInдля проверки свойства Quick_Check заданной формы нормализации. - Доступ к большому количеству часто используемых наборов кодовых точек. Поддерживаемые наборы включают сценарий, блок и общую категорию. Точное содержимое набора можно увидеть в утилите CLDR на странице индекса свойств property index веб-сайта Юникода. См.
unicodeдля легкого и (необязательно) проверенного на этапе компиляции запроса наборы.
Резюме
import std.uni;
void main()
{
// initialize code point sets using script/block or property name
// now 'set' contains code points from both scripts.
auto set = unicode("Cyrillic") | unicode("Armenian");
// same thing but simpler and checked at compile-time
auto ascii = unicode.ASCII;
auto currency = unicode.Currency_Symbol;
// easy set ops
auto a = set & ascii;
assert(a.empty); // as it has no intersection with ascii
a = set | ascii;
auto b = currency - a; // subtract all ASCII, Cyrillic and Armenian
// some properties of code point sets
assert(b.length > 45); // 46 items in Unicode 6.1, even more in 6.2
// testing presence of a code point in a set
// is just fine, it is O(logN)
assert(!b['$']);
assert(!b['\u058F']); // Armenian dram sign
assert(b['¥']);
// building fast lookup tables, these guarantee O(1) complexity
// 1-level Trie lookup table essentially a huge bit-set ~262Kb
auto oneTrie = toTrie!1(b);
// 2-level far more compact but typically slightly slower
auto twoTrie = toTrie!2(b);
// 3-level even smaller, and a bit slower yet
auto threeTrie = toTrie!3(b);
assert(oneTrie['£']);
assert(twoTrie['£']);
assert(threeTrie['£']);
// build the trie with the most sensible trie level
// and bind it as a functor
auto cyrillicOrArmenian = toDelegate(set);
auto balance = find!(cyrillicOrArmenian)("Hello ընկեր!");
assert(balance == "ընկեր!");
// compatible with bool delegate(dchar)
bool delegate(dchar) bindIt = cyrillicOrArmenian;
// Normalization
string s = "Plain ascii (and not only), is always normalized!";
assert(s is normalize(s));// is the same string
string nonS = "A\u0308ffin"; // A ligature
auto nS = normalize(nonS); // to NFC, the W3C endorsed standard
assert(nS == "Äffin");
assert(nS != nonS);
string composed = "Äffin";
assert(normalize!NFD(composed) == "A\u0308ffin");
// to NFKD, compatibility decomposition useful for fuzzy matching/searching
assert(normalize!NFKD("2¹⁰") == "210");
}
Терминология
Ниже приведён список важных понятий и определений Юникода. Любые соглашения, используемые только в данном модуле, отмечены как таковые. Описания основаны на формальном определении, как указано в главе три Unicode Standard Core Specification.
Абстрактный символ Единица информации, используемая для организации, управления или представления текстовых данных. Обратите внимание:- При представлении данных характер данных, как правило, символический, а не какого-либо другого типа (например, визуальный).
- У абстрактного символа нет конкретной формы и его не следует путать с глифом.
- Абстрактный символ не обязательно соответствует тому, что пользователь понимает под «символом», и его не следует путать с
Grapheme. - Абстрактные символы, закодированные (см. Закодированный символ), известны как абстрактные символы Юникода.
- Абстрактные символы, не закодированные в стандарте Юникод, часто могут быть представлены с помощью последовательностей комбинируемых символов.
char), 16-битные код-единицы в UTF-16 (wchar) и 32-битные код-единицы в UTF-32 (dchar). Обратите внимание, что в UTF-32 код-единица — это кодовая точка и представлена типом D dchar.Комбинирующий символ Символ с общей категорией Комбинирующий знак (M). - Все символы с ненулевым классом комбинирования являются комбинирующими символами, но обратное неверно: есть комбинирующие символы с нулевым классом комбинирования.
- Эти символы обычно не используются изолированно, если только они не описываются. К ним относятся такие символы, как акценты, диакритические знаки, еврейские точки, арабские гласные знаки и индийские матрасы.
- Кластер графем представляет собой горизонтально сегментируемую единицу текста, состоящую из некоторой базы графемы (которая может состоять из корейского слога) вместе с любым количеством знаков без интервалов, примененных к ней.
- Кластер графем обычно начинается с базы графемы и затем распространяется на любую последующую последовательность знаков без интервалов. Кластер графем наиболее непосредственно относится к отображению текста и процессам, таким как позиционирование курсора и выделение текста в редактировании, но также может быть связан с сравнением и поиском.
- Для многих процессов кластер графем ведет себя так, как если бы это был один символ с теми же свойствами, что и его база графемы. По существу, знаки без интервалов применяются *графически* к базе, но не изменяют ее свойства.
Этот модуль определяет ряд примитивов, работающих с графемами: Grapheme, decodeGrapheme и graphemeStride. Все они используют границы *расширенной графемы*, как определено в упомянутом выше стандартном приложении.
Нормализация
Концепции канонически эквивалентных или совместимых эквивалентных символов в стандарте Юникода требуют полного формального определения эквивалентности для строк Юникода. Эквивалентность строк определяется процессом, называемым нормализацией, при котором строки преобразуются в формы, которые сравниваются напрямую на равенство. Это основная цель процесса нормализации, см. функцию normalize для преобразования в любую из четырех определенных форм.
Очень важным свойством форм нормализации Юникода является то, что они должны оставаться стабильными между версиями стандарта Юникода. Строка Юникода, нормализованная до определенной формы нормализации Юникода в одной версии стандарта, гарантированно останется в этой форме нормализации для реализаций будущих версий стандарта.
Стандарт Юникода определяет четыре формы нормализации. Неформально, две из этих форм определяются максимальной декомпозицией эквивалентных последовательностей, а две из этих форм определяются максимальной *композицией* эквивалентных последовательностей.
- Форма нормализации D (NFD): каноническая декомпозиция последовательности символов.
- Форма нормализации KD (NFKD): декомпозиция совместимости последовательности символов.
- Форма нормализации C (NFC): Каноническое объединение канонической декомпозиции закодированной последовательности символов.
- Форма нормализации KC (NFKC): Каноническое объединение декомпозиции совместимости последовательности символов
Выбор формы нормализации зависит от конкретного случая использования. NFC — лучшая форма для общего текста, так как она лучше совместима со строками, преобразованными из устаревших кодировок. NFKC — предпочтительная форма для идентификаторов, особенно там, где существуют проблемы безопасности. NFD и NFKD наиболее полезны для внутренней обработки.
Создание таблиц поиска
Стандарт Юникода описывает набор алгоритмов, которые зависят от возможности быстрого поиска различных свойств кодового значения. Учитывая пространство кодирования около 1 миллиона кодовых точек, это нетривиальная задача обеспечить экономичное по памяти решение для множества свойств.
Общие подходы, такие как хеш-таблицы или бинарный поиск по отсортированным интервалам кодовых точек (как в InversionList), недостаточны. Хеш-таблицы имеют огромный объем памяти, а бинарный поиск по интервалам недостаточно быстр для некоторых сложных алгоритмов.
Рекомендуемое решение (см. Руководство по реализации Юникода) — использование таблиц с несколькими этапами, которые являются реализацией структуры данных Trie с целочисленными ключами и фиксированным числом этапов. В дальнейшем это будет называться фиксированным деревом Trie. Ниже описана конкретная реализация, нацеленная на скорость доступа в ущерб идеальной экономии памяти.
Взяв в качестве примера дерево Trie с 2 уровнями, принцип работы таков. Разбейте количество бит в ключе (кодовая точка, 21 бит) на 2 компонента (например, 15 и 8). Первое — количество бит в индексе дерева Trie, а второе — количество бит в каждой странице дерева Trie. Затем расположение дерева Trie — это массив размером 2^^количество бит в индексе, за которым следует массив блоков памяти размером 2^^количество бит в странице/бит на элемент.
Количество страниц является переменным (но не менее 1), в отличие от количества записей в индексе. Все ячейки индекса должны содержать номер присутствующей страницы. Затем поиск — всего лишь несколько операций: вырезание старших битов, поиск индекса для них, взятие страницы в этом индексе и использование младших битов в качестве смещения в этой странице.
Предполагая, что страницы расположены последовательно в одном массиве в
pages, псевдокод выглядит следующим образом: auto elemsPerPage = (2 ^^ bits_per_page) / Value.sizeOfInBits; pages[index[n >> bits_per_page]][n & (elemsPerPage - 1)];
Где, если elemsPerPage является степенью 2, весь процесс сводится к нескольким простым командам и 2 чтений массива. Последующие уровни дерева Trie вводятся путем рекурсии над этим понятием — массив индекса рассматривается как значения. Затем количество бит в индексе снова делится на 2 части, с страницами над 'текущий-индекс' и новым 'верхний-индекс'.
Для полноты картины дерево Trie уровня 1 — это просто массив. Текущая реализация использует упаковку битов, когда диапазон заранее известен и ограничен (например, bool). См. также BitPacked для принудительного его использования вручную. Однако основное преимущество по размеру заключается в том, что по конструкции сливаются несколько одинаковых страниц на каждом уровне.
Процесс построения дерева Trie более сложен и скрыт от пользователя в виде удобных функций codepointTrie, codepointSetTrie и еще более удобной toTrie. В общем случае множество или встроенный AA с dchar типом можно преобразовать в дерево Trie. Объект Trie в этом модуле является только для чтения (неизменяемым); он фактически замораживается после построения.
Свойства Юникода
Это полный список свойств Юникода, доступных через unicode со специфическими вспомогательными функциями по каждой категории внутри. В случае сомнений обратитесь к утилите CLDR.
Перечисленные ниже наборы общей категории доступны только с помощью сокращенного доступа unicode.
| Сокр. | Полное название | Сокр. | Полное название | Сокр. | Полное название |
|---|---|---|---|---|---|
| L | Буква | Cn | Неназначено | Po | Прочие знаки препинания |
| Ll | Строчная буква | Co | Частное использование | Ps | Открывающие знаки препинания |
| Lm | Модификаторная буква | Cs | Супплемент | S | Символ |
| Lo | Другая буква | N | Число | Sc | Символ валюты |
| Lt | Заглавная буква | Nd | Десятичное число | Sk | Символ модификатора |
| Lu | Прописная буква | Nl | Число-буква | Sm | Математический символ |
| M | Знак | No | Другое число | So | Другой символ |
| Mc | Знак с интервалом | P | Знак препинания | Z | Разделитель |
| Me | Закрывающий знак | Pc | Соединительный знак препинания | Zl | Разделитель строки |
| Mn | Знак без интервала | Pd | Знак тире | Zp | Разделитель абзаца |
| C | Другое | Pe | Закрывающий знак препинания | Zs | Пробельный разделитель |
| Cc | Управляющий символ | Pf | Конечный знак препинания | - | Любой |
| Cf | Формат | Pi | Начальный знак препинания | - | ASCII |
Наборы других часто полезных свойств, доступных с помощью unicode:
| Имя | Имя | Имя |
|---|---|---|
| Буква | Идеографическое | Другие_заглавные |
| ASCII_шестнадцатеричная_цифра | IDS_двоичный_оператор | Синтаксис_шаблона |
| Управление_биди | Начало_IDS | Пробел_шаблона |
| С заглавной буквы | IDS_троичный_оператор | Знак_кавычек |
| Игнорируемая_с_точки_зрения_регистра | Управление_соединением | Корень |
| Дефис | Исключение_порядка_логики | Мягкая_точка |
| Знак_по умолчанию_игнорируемый_код_символа | Строчные | STerm |
| Устаревший | Математический | Заключительная_пунктуация |
| Диакритический | Код_символа_без_символа | Объединённый_идеографический |
| Расширитель | Другие_буквенные | Прописные |
| Основная_часть_графического_символа | Другие_знаки_по_умолчанию_игнорируемые_код_символа | Селектор_варианта |
| Расширение_графического_символа | Другие_расширение_графического_символа | Пробел |
| Связь_графического_символа | Другие_ID_продолжение | XID_продолжение |
| Шестнадцатеричная_цифра | Другие_ID_начало | XID_начало |
| Тире | Другие_строчные | |
| ID_продолжение | Другие_математические |
Ниже приведена таблица с именами блоков, которые принимаются unicode.block. Обратите внимание, что сокращённая версия unicode требует добавления «In» перед именами блоков для устранения неоднозначности между письменностями и блоками.
| Числа_Эгейского_мира | Расширенный_эфиопский | Монгольский |
| Символы_алхимии | Расширенный_эфиопский-A | Музыкальные_символы |
| Формы_представления_алфавитов | Дополнительный_эфиопский | Мьянма |
| Древнегреческая_нотация_музыки | Общие_знаки_препинания | Расширенный_мьянма-A |
| Древнегреческие_числа | Геометрические_фигуры | Новый_тай_люй |
| Древние_символы | Грузинский | NKo |
| Арабский | Дополнительный_грузинский | Формы_чисел |
| Расширенный_арабский-A | Глаголический | Огам |
| Арабские_математические_символы_алфавита | Готский | Ол_чики |
| Арабские_формы_представления-A | Греческий_и_коптский | Староиталийский |
| Арабские_формы_представления-B | Расширенный_греческий | Староперсидский |
| Дополнительный_арабский | Гуджарати | Староаравийский |
| Армянский | Гурмукхи | Старотурецкий |
| Стрелки | Формы_полуширин_и_полных_ширин | Оптическое_распознавание_символов |
| Авестийский | Совместимость_хангуля_джамо | Ориясский |
| Балийский | Хангуль_джамо | Османский |
| Бамум | Расширенный_хангуль_джамо-A | Фагс-па |
| Дополнительный_бамум | Расширенный_хангуль_джамо-B | Диск_Фаистоса |
| Основной_латинский | Слоги_хангуля | Финикийский |
| Батак | Хануну | Фонемные_расширения |
| Бенгальский | Иврит | Дополнительные_фонемные_расширения |
| Элементы_блока | Символы_идеографического_описания | Карты_для_игры |
| Брахими | Императорский_арамейский | Рунический |
| Узоры_брайля | Надписи_пахлави | Самартианский |
| Бугинезийский | Надписи_парфянский | Саураштра |
| Бухид | Расширения_МФА | Шарида |
| Византийские_символы_музыки | Яванский | Шавьин |
| Карийский | Кайти | Сингальский |
| Чакма | Дополнительный_канадский | Малые_варианты_форм |
| Чам | Канбун | Сора_Сомпэн |
| Чернокожий | Корни_Канкси | Пробельные_модификаторы_букв |
| Совместимость_CJK | Каннада | Спецсимволы |
| Формы_совместимости_CJK | Катакана | Сунданийский |
| Идеограммы_совместимости_CJK | Фонемные_расширения_катаканы | Дополнительный_сунданийский |
| Дополнительные_идеограммы_совместимости_CJK | Кайя_Ли | Надстрочные_и_подстрочные_символы |
| Дополнительные_корни_CJK | Кхароштхи | Дополнительные_стрелки-A |
| Штрихи_CJK | Кхмерский | Дополнительные_стрелки-B |
| Символы_и_знаки_препинания_CJK | Символы_кхмерского | Дополнительные_математические_операторы |
| Объединённые_идеограммы_CJK | Лаосский | Дополнительные_знаки_препинания |
| Расширение_объединённых_идеограмм_CJK_A | Дополнительный_латинский-1 | Дополнительная_область_для_частного_использования-A |
| Расширение_объединённых_идеограмм_CJK_B | Дополнительный_латинский_A | Дополнительная_область_для_частного_использования-B |
| Расширение_объединённых_идеограмм_CJK_C | Дополнительный_дополнительный_латинский | Силоти_Нагри |
| Расширение_объединённых_идеограмм_CJK_D | Дополнительный_латинский_B | Сирийский |
| Комбинирующие_диакритические_знаки | Дополнительный_латинский_C | Тагалог |
| Комбинирующие_диакритические_знаки_для_символов | Дополнительный_латинский_D | Тагбануа |
| Дополнительные_комбинирующие_диакритические_знаки | Лэпча | Теги |
| Комбинирующие_полузнаки | Символы_в_виде_букв | Тай_Люй |
| Общие_индийские_формы_чисел | Лимбу | Тай_Там |
| Изображения_управления | Идеограммы_линейного_B | Тай_Вьет |
| Кптский | Силлабический_линейный_B | Символы_тай_сюань_цзин |
| Числа_счёта_палочек | Лисю | Такри |
| Клинопись | Низкие_суперпозиции | Тамильский |
| Клинописные_числа_и_знаки_препинания | Ликийский | Телугу |
| Символы_валют | Лидийский | Таана |
| Кипрский_силлабический | Плитка_для_маджонга | Тай |
| Кириллический | Малаялам | Тибетский |
| Расширенный_кириллический-A | Мандейский | Символы_тифинага |
| Расширенный_кириллический-B | Математические_алфавитно-цифровые_символы | Символы_транспорта_и_карт |
| Дополнительный_кириллический | Математические_операторы | Угаритский |
| Дезерет | Метей_Маек | Объединённые_канадские_символы_коренных_народов |
| Деванагари | Расширения_Метей_Маек | Расширенные_объединённые_канадские_символы_коренных_народов |
| Расширенный_деванагари | Мероитский_курсив | Вай |
| Символы_динбатов | Мероитские_иероглифы | Расширения_ведических |
| Кости_домино | Мьяо | Вертикальные_формы |
| Египетские_иероглифы | Разные_математические_символы_A | Символы_и_гексаграммы_ИЦзин |
| Иконки | Разные_математические_символы_B | Корни_И |
| Вложенные_алфавитно-цифровые_знаки | Разные_символы | |
| Дополнительные_вложенные_алфавитно-цифровые_знаки | Разные_символы_и_стрелки | |
| Вложенные_буквы_и_месяцы_CJK | Разные_символы_и_пиктограммы | |
| Дополнительные_вложенные_идеограммы | Разные_технические | |
| Эфиопский | Модификаторы_тональных_букв |
Ниже приведена таблица с именами письменностей, принятых unicode.script и сокращённой версией unicode:
| Арабский | Хануну | Староиталийский |
| Армянский | Иврит | Староперсидский |
| Авестийский | Хирагана | Староаравийский |
| Балийский | Императорский_арамейский | Старотурецкий |
| Бамум | Наследуемый | Ориясский |
| Батак | Надписи_пахлави | Османский |
| Бенгальский | Надписи_парфянский | Фагс-па |
| Бопомофо | Яванский | Финикийский |
| Брахими | Кайти | Рунический |
| Брайль | Каннада | Самартианский |
| Бугинезийский | Катакана | Саураштра |
| Бухид | Кайя_Ли | Шарида |
| Канадский_коренной | Кхароштхи | Шавьин |
| Карийский | Кхмерский | Сингальский |
| Чакма | Лаосский | Сора_Сомпэн |
| Чам | Латинский | Сунданийский |
| Чернокожий | Лэпча | Силоти_Нагри |
| Общий | Лимбу | Сирийский |
| Коптский | Линейный_B | Тагалог |
| Клинопись | Лисю | Тагбануа |
| Кипрский | Ликийский | Тай_Люй |
| Кириллический | Лидийский | Тай_Там |
| Дезерет | Малаялам | Тай_Вьет |
| Деванагари | Мандейский | Такри |
| Египетские_иероглифы | Метей_Маек | Тамильский |
| Эфиопский | Мероитский_курсив | Телугу |
| Грузинский | Мероитские_иероглифы | Таана |
| Глаголический | Мьяо | Тай |
| Готский | Монгольский | Тибетский |
| Греческий | Мьянма | Тифинаг |
| Гуджарати | Новый_тай_люй | Угаритский |
| Гурмукхи | NKo | Вай |
| Хан | Огам | И |
| Хангуль | Ол_чики |
Ниже приведена таблица имён, принятых unicode.hangulSyllableType.
| Сокр. | Полная_форма |
|---|---|
| L | Ведущая_джамо |
| LV | LV_слог |
| LVT | LVT_слог |
| T | Завершающая_джамо |
| V | Гласная_джамо |
- Ссылки
- Таблица_ASCII, Википедия, Консорциум_Unicode, Формы_нормализации_Unicode, Сегментация_текста_Unicode Руководство_по_реализации_Unicode Соответствие_Unicode
- Торговые_знаки
- Unicode(tm) — торговая_марка_Unicode, Inc.
- Лицензия:
- Лицензия_Boost_1.0.
- Авторы:
- Дмитрий_Ольшанский
- Источник
- std/uni/package.d
- Стандарты:
- Unicode v6.2
- enum dchar lineSep;
-
Постоянная кодовая точка (0x2028) — разделитель строк.
- enum dchar paraSep;
-
Постоянная кодовая точка (0x2029) — разделитель абзацев.
- enum dchar nelSep;
-
Постоянная кодовая точка (0x0085) — следующая строка.
- template isCodepointSet(T)
-
Проверяет, является ли T каким-то типом набора кодовых точек. Предназначено для ограничений шаблонов.
- enum auto isIntegralPair(T, V = uint);
-
Проверяет, является ли
Tпарой целых чисел, которые неявно преобразуются вV. Следующий код должен компилироваться для любой парыT:(T x){ V a = x[0]; V b = x[1];}Следующее не должно компилироваться:(T x){ V c = x[2];} - alias CodepointSet = InversionList!(GcPolicy).InversionList;
-
Рекомендуемый тип по умолчанию для набора кодовых точек. Подробнее см. текущую реализацию:
InversionList. - struct CodepointInterval;
-
Рекомендуемый тип
std.typecons.Tupleдля представления интервалов [a, b) кодовых точек. Используется вInversionList. Любой тип интервала должен удовлетворять свойствуisIntegralPair. - struct InversionList(SP = GcPolicy);
-
InversionList— это множество кодовых точек, представленное в виде массива интервалов открытых справа [a, b) (см.CodepointIntervalвыше). Название происходит от способа чтения представления слева направо. Например, множество всех значений [10, 50), [80, 90) плюс отдельное значение 60 выглядит следующим образом:10, 50, 60, 61, 80, 90
Способ чтения: начинаем с отрицательного значения, обозначающего, что все числа, меньшие следующего, отсутствуют в этом множестве (и положительного — наоборот). Затем меняем положительное/отрицательное после каждого пройденного числа слева направо.
Таким образом, отрицательные значения продолжаются до 10, затем положительные до 50, затем отрицательные до 60, затем положительные до 61 и так далее. Как видно, это обеспечивает экономичное хранение высокоизбыточных данных, которые встречаются длинными сериями. Описание, которое хорошо подходит для свойств Unicode символов. Сам метод можно рассматривать как разновидность RLE-кодирования.
Множества — это значения типов (так же, как и
int), поэтому они никогда не дублируются.- Пример
auto a = CodepointSet('a', 'z'+1); auto b = CodepointSet('A', 'Z'+1); auto c = a; a = a | b; assert(a == CodepointSet('A', 'Z'+1, 'a', 'z'+1)); assert(a != c);См. также
unicodeдля более простого создания наборов из предварительно заданных.Объем памяти составляет 8 байт на каждый смежный интервал в наборе. Семантика значений достигается с помощью техники COW, и поэтому не безопасно приводить этот тип к типу shared.
- Примечание
Не рекомендуется полагаться на параметры шаблона или точный тип текущего набора кодовых точек в
std.uni. Тип и параметры могут измениться при окончательном проектировании стандартных аллокаторов. ИспользуйтеisCodepointSetс шаблонами или просто придерживайтесь по умолчанию псевдонимаCodepointSetпо всему коду.- pure this(Set)(Set set)
Constraints: if (isCodepointSet!Set); -
Создание из другого набора кодовых точек любого типа.
- pure this(Range)(Range intervals)
Constraints: if (isForwardRange!Range && isIntegralPair!(ElementType!Range)); -
Создание множества из упорядоченного диапазона интервалов кодовых точек.
- this()(uint[] intervals...);
-
Создание множества из простых значений интервалов кодовых точек.
- Примеры:
-
import std.algorithm.comparison : equal; auto set = CodepointSet('a', 'z'+1, 'а', 'я'+1); foreach (v; 'a'..'z'+1) assert(set[v]); // Cyrillic lowercase interval foreach (v; 'а'..'я'+1) assert(set[v]); //specific order is not required, intervals may interesect auto set2 = CodepointSet('а', 'я'+1, 'a', 'd', 'b', 'z'+1); //the same end result assert(set2.byInterval.equal(set.byInterval)); // test constructor this(Range)(Range intervals) auto chessPiecesWhite = CodepointInterval(9812, 9818); auto chessPiecesBlack = CodepointInterval(9818, 9824); auto set3 = CodepointSet([chessPiecesWhite, chessPiecesBlack]); foreach (v; '♔'..'♟'+1) assert(set3[v]);
- @property scope auto byInterval();
-
Получение диапазона, охватывающего все интервалы кодовых точек в этом
InversionList. - const bool opIndex(uint val);
-
Проверка наличия кодовой точки
valв этом наборе.- Примеры:
-
auto gothic = unicode.Gothic; // Gothic letter ahsa assert(gothic['\U00010330']); // no ascii in Gothic obviously assert(!gothic['$']);
- @property size_t length();
-
Количество кодовых точек в этом наборе.
- This opBinary(string op, U)(U rhs)
Constraints: if (isCodepointSet!U || is(U : dchar)); -
Множества поддерживают естественный синтаксис для алгебры множеств, а именно:
Оператор Математическая запись Описание & a ∩ b пересечение | a ∪ b объединение - a ∖ b вычитание ~ a ~ b симметрическая разность, т.е. (a ∪ b) \ (a ∩ b) - Примеры:
-
import std.algorithm.comparison : equal; import std.range : iota; auto lower = unicode.LowerCase; auto upper = unicode.UpperCase; auto ascii = unicode.ASCII; assert((lower & upper).empty); // no intersection auto lowerASCII = lower & ascii; assert(lowerASCII.byCodepoint.equal(iota('a', 'z'+1))); // throw away all of the lowercase ASCII writeln((ascii - lower).length); // 128 - 26 auto onlyOneOf = lower ~ ascii; assert(!onlyOneOf['Δ']); // not ASCII and not lowercase assert(onlyOneOf['$']); // ASCII and not lowercase assert(!onlyOneOf['a']); // ASCII and lowercase assert(onlyOneOf['я']); // not ASCII but lowercase // throw away all cased letters from ASCII auto noLetters = ascii - (lower | upper); writeln(noLetters.length); // 128 - 26 * 2
- ref This opOpAssign(string op, U)(U rhs)
Constraints: if (isCodepointSet!U || is(U : dchar)); -
Версии 'op=' перечисленных выше перегруженных операторов.
- const bool opBinaryRight(string op : "in", U)(U ch)
Constraints: if (is(U : dchar)); -
Проверка наличия кодовой точки
chв этом наборе, то же, что иopIndex.- Примеры:
-
assert('я' in unicode.Cyrillic); assert(!('z' in unicode.Cyrillic));
- auto opUnary(string op : "!")();
-
Получение набора, являющегося инверсией этого набора.
- См. также:
inverted
- @property auto byCodepoint();
-
Диапазон, охватывающий каждую кодовую точку в этом наборе.
- Примеры:
-
import std.algorithm.comparison : equal; import std.range : iota; auto set = unicode.ASCII; set.byCodepoint.equal(iota(0, 0x80));
- void toString(Writer)(scope Writer sink, ref scope const FormatSpec!char fmt);
-
Получение текстового представления этого InversionList в виде интервалов открытых справа.
Флаг форматирования применяется индивидуально к каждому значению, например:
- %s и %d форматируют интервалы как диапазон [низкое .. высокое) целых чисел
- %x форматирует интервалы как диапазон [низкое .. высокое) строчных шестнадцатеричных символов
- %X форматирует интервалы как диапазон [низкое .. высокое) прописных шестнадцатеричных символов
- Примеры:
-
import std.conv : to; import std.format : format; import std.uni : unicode; assert(unicode.Cyrillic.to!string == "[1024..1157) [1159..1320) [7467..7468) [7544..7545) [11744..11776) [42560..42648) [42655..42656)"); // The specs '%s' and '%d' are equivalent to the to!string call above. writeln(format("%d", unicode.Cyrillic)); // unicode.Cyrillic.to!string assert(format("%#x", unicode.Cyrillic) == "[0x400..0x485) [0x487..0x528) [0x1d2b..0x1d2c) [0x1d78..0x1d79) [0x2de0..0x2e00) " ~"[0xa640..0xa698) [0xa69f..0xa6a0)"); assert(format("%#X", unicode.Cyrillic) == "[0X400..0X485) [0X487..0X528) [0X1D2B..0X1D2C) [0X1D78..0X1D79) [0X2DE0..0X2E00) " ~"[0XA640..0XA698) [0XA69F..0XA6A0)");
- ref auto add()(uint a, uint b);
-
Добавление интервала [a, b) в этот набор.
- Примеры:
-
CodepointSet someSet; someSet.add('0', '5').add('A','Z'+1); someSet.add('5', '9'+1); assert(someSet['0']); assert(someSet['5']); assert(someSet['9']); assert(someSet['Z']);
- @property auto inverted();
-
Получение набора, являющегося инверсией этого набора.
См. '!'
opUnaryдля того же, но с использованием операторов.- Примеры:
-
auto set = unicode.ASCII; // union with the inverse gets all of the code points in the Unicode writeln((set | set.inverted).length); // 0x110000 // no intersection with the inverse assert((set & set.inverted).empty);
- string toSourceCode(string funcName = "");
-
Генерирует строку с кодом D унарной функции с именем
funcName, принимающей один аргументdchar. ЕслиfuncNameпуста, код корректируется для создания лямбда-функции.Созданная функция проверяет, принадлежит ли переданная кодовая точка этому набору или нет. Результат должен использоваться с миксином строк. Предполагаемая область использования — агрессивная оптимизация с помощью метапрограммирования в генераторах парсеров и подобных инструментах.
- Примечание
- Используйте с осторожностью для относительно небольших или регулярных наборов. Это может оказаться медленнее, чем использование многоступенчатых таблиц.
- Пример
import std.stdio; // construct set directly from [a, b$RPAREN intervals auto set = CodepointSet(10, 12, 45, 65, 100, 200); writeln(set); writeln(set.toSourceCode("func"));Выше приводится что-то вроде:bool func(dchar ch) @safe pure nothrow @nogc { if (ch < 45) { if (ch == 10 || ch == 11) return true; return false; } else if (ch < 65) return true; else { if (ch < 100) return false; if (ch < 200) return true; return false; } } - const @property bool empty();
-
Истинно, если этот набор не содержит кодовых точек.
- Примеры:
-
CodepointSet emptySet; writeln(emptySet.length); // 0 assert(emptySet.empty);
- template codepointSetTrie(sizes...) if (sumOfIntegerTuple!sizes == 21)
-
Сокращенное обозначение для создания настраиваемого фиксированного дерева Trie нескольких уровней из
CodepointSet.sizes— это числа битов на уровень, начиная с наиболее значимых битов.- Примечание
- Сумма
sizesдолжна быть равна 21.
- См. также:
-
toTrie, что еще проще.
- Пример
{ import std.stdio; auto set = unicode("Number"); auto trie = codepointSetTrie!(8, 5, 8)(set); writeln("Input code points to test:"); foreach (line; stdin.byLine) { int count=0; foreach (dchar ch; line) if (trie[ch])// is number count++; writefln("Contains %d number code points.", count); } } - template CodepointSetTrie(sizes...) if (sumOfIntegerTuple!sizes == 21)
-
Тип дерева Trie, сгенерированного функцией codepointSetTrie.
- template codepointTrie(T, sizes...) if (sumOfIntegerTuple!sizes == 21)
template CodepointTrie(T, sizes...) if (sumOfIntegerTuple!sizes == 21)
-
Несколько более универсальный инструмент для построения фиксированных
Trieдля данных Юникода.В частности, в отличие от
codepointSetTrie, он позволяет создавать отображенияdcharна произвольный типT.- Примечание
- Перегрузка, принимающая
CodepointSet, будет естественным образом преобразовывать только в булево отображениеTrie.
- auto codepointTrie()(T[dchar] map, T defValue = T.init);
- auto codepointTrie(R)(R range, T defValue = T.init)
Constraints: if (isInputRange!R && is(typeof(ElementType!R.init[0]) : T) && is(typeof(ElementType!R.init[1]) : dchar));
- struct MatcherConcept;
-
Концептуальный тип, описывающий общие свойства всех UTF-матчеров.
- Примечание
- Только для иллюстративных целей, каждый вызов метода приводит к ошибке утверждения. Используйте
utfMatcherдля получения конкретного матчера для кодировок UTF-8 или UTF-16.
- bool match(Range)(ref Range inp)
Constraints: if (isRandomAccessRange!Range && is(ElementType!Range : char));
bool skip(Range)(ref Range inp)
Constraints: if (isRandomAccessRange!Range && is(ElementType!Range : char));
bool test(Range)(ref Range inp)
Constraints: if (isRandomAccessRange!Range && is(ElementType!Range : char)); -
Выполняет семантически эквивалентные 2 операции: декодирование кодовой точки в начале
inpи проверка принадлежности ее к набору кодовых точек этого матчера.Воздействие на
inpзависит от вызываемой функции:
Match. Если кодовая точка найдена в наборе, то диапазон
inpсдвигается на свою длину в кодовых единицах, в противном случае диапазон не изменяется.
Skip. Диапазон всегда сдвигается на длину тестируемой кодовой точки, независимо от результата проверки.
Test. Диапазон остается неизменным независимо от результата проверки.
- Примеры:
-
string truth = "2² = 4"; auto m = utfMatcher!char(unicode.Number); assert(m.match(truth)); // '2' is a number all right assert(truth == "² = 4"); // skips on match assert(m.match(truth)); // so is the superscript '2' assert(!m.match(truth)); // space is not a number assert(truth == " = 4"); // unaffected on no match assert(!m.skip(truth)); // same test ... assert(truth == "= 4"); // but skips a codepoint regardless assert(!m.test(truth)); // '=' is not a number assert(truth == "= 4"); // test never affects argument
- @property auto subMatcher(Lengths...)();
-
Дополнительно - обеспечивает прямой доступ к подмножеству матчера на основе набора известных длин кодирования. Длины указываются в кодовых единицах. Подматчер затем может выполнять меньше операций на каждые
test/match.Используйте с осторожностью, так как подматчер не будет соответствовать никаким кодовым точкам, длина кодирования которых не принадлежит выбранному набору длин. Также объект подматчера ссылается на родительский матчер и не должен использоваться после окончания срока службы последнего.
Еще одним недостатком использования подматчера является то, что skip недоступен именно потому, что подматчер не обнаруживает все длины.
- enum auto isUtfMatcher(M, C);
-
Проверка, является ли
MUTF-матчером для диапазоновChar. - auto utfMatcher(Char, Set)(Set set)
Constraints: if (isCodepointSet!Set); -
Создает объект матчера для классификации кодовых точек из
setдля кодирования, у которогоCharявляется кодовой единицей.См.
MatcherConceptдля обзора API. - auto toTrie(size_t level, Set)(Set set)
Constraints: if (isCodepointSet!Set); -
Удобная функция для построения оптимальных конфигураций упакованного Trie из любого
Параметрsetкодовых точек.levelуказывает количество уровней trie для использования, допустимые значения: 1, 2, 3 или 4. Уровни представляют различные компромиссы со скоростью и размером.
Уровень 1 самый быстрый и самый емкий в памяти (массив битов).
Уровень 4 самый медленный и имеет наименьший объем памяти.
См. раздел Synopsis для примера.- Примечание
- Уровень 4 остается очень практичным (быстрее и предсказуемее), по сравнению с использованием прямого поиска в самом
set.
- auto toDelegate(Set)(Set set)
Constraints: if (isCodepointSet!Set); -
Строит
Trieс типично оптимальным компромиссом между скоростью и размером и оборачивает его в делегат следующего типа:bool delegate(dchar ch).По сути, это создает лямбда-«тестер», подходящий для алгоритмов, таких как std.algorithm.find, которые принимают унарные предикаты.
См. раздел Synopsis для примера. - struct unicode;
-
Единственная точка входа для поиска наборов Юникод кодовых точек по имени или псевдониму блока, сценария или общей категории.
Использует хорошо определенные стандартные правила поиска по имени свойства. Это включает в себя нечеткое соответствие имен, поэтому «White_Space», «white-SpAce» и «whitespace» считаются равными и приводят к одному и тому же набору пробельных символов.
- pure @property auto opDispatch(string name)();
-
Выполняет поиск набора кодовых точек с проверкой корректности на этапе компиляции. Эта короткая версия объединяет 3 поиска: по блокам, сценариям и общим двоичным свойствам.
Обратите внимание, что поскольку сценарии и блоки перекрываются, используется обычный трюк для устранения неоднозначности — для получения блока используйте
unicode.InBlockName, для поиска сценария используйтеunicode.ScriptName.- См. также:
-
block,scriptи (не включено в этот поиск)hangulSyllableType.
- auto opCall(C)(scope const C[] name)
Constraints: if (is(C : dchar)); -
Тот же поиск по блокам, сценариям или двоичным свойствам, но выполняемый во время выполнения. Эта версия предоставляется для случаев, когда
nameне известны заранее; в противном случае проверенная на этапе компиляцииopDispatchобычно является лучшим выбором.См. таблицу свойств Юникода для доступных наборов.
- struct block;
-
Сужает поиск наборов кодовых точек до всех блоков Юникода.
- Примечание
- Здесь имена блоков недвусмысленные, так как сценарии не проверяются, и таким образом для поиска используется просто обозначение
unicode.block.BlockName.
- См. также:
- таблица свойств.
- Примеры:
-
// use .block for explicitness writeln(unicode.block.Greek_and_Coptic); // unicode.InGreek_and_Coptic
- struct script;
-
Сужает поиск наборов кодовых точек до всех сценариев Юникода.
См. таблицу свойств Юникода для доступных наборов.
- Примеры:
-
auto arabicScript = unicode.script.arabic; auto arabicBlock = unicode.block.arabic; // there is an intersection between script and block assert(arabicBlock['']); assert(arabicScript['']); // but they are different assert(arabicBlock != arabicScript); writeln(arabicBlock); // unicode.inArabic writeln(arabicScript); // unicode.arabic
- struct hangulSyllableType;
-
Получение набора кодовых точек, имеющих заданный тип слога хангул.
Другие свойства, не являющиеся двоичными (если будут поддерживаться), следуют той же нотации —
unicode.propertyName.propertyValueдля проверки на этапе компиляции иunicode.propertyName(propertyValue)для проверки во время выполнения.
См. таблицу свойств Юникода для доступных наборов.- Примеры:
-
// L here is syllable type not Letter as in unicode.L short-cut auto leadingVowel = unicode.hangulSyllableType("L"); // check that some leading vowels are present foreach (vowel; '\u1110'..'\u115F') assert(leadingVowel[vowel]); writeln(leadingVowel); // unicode.hangulSyllableType.L
- CodepointSet parseSet(Range)(ref Range range, bool casefold = false)
Constraints: if (isInputRange!Range && is(ElementType!Range : dchar)); -
Парсинг набора кодовых точек Юникода из заданного
rangeс использованием стандартного синтаксиса регулярных выражений '[...]'. Диапазон сдвигается, пропуская определение набора регулярных выражений. Параметрcasefoldопределяет, должен ли набор быть преобразован в регистр — то есть, включать как строчные, так и прописные версии для любых букв в наборе.
- pure @safe size_t graphemeStride(C)(scope const C[] input, size_t index)
Constraints: if (is(C : dchar)); -
Вычисляет длину кластера графем, начинающегося с
index. И полученная длина, иindexизмеряются в кодовых единицах.- Параметры:
C тип, неявно преобразуемый в dcharsC[] inputмассив кластеров графем size_t indexначальный индекс в input[]
- Возвращает:
- длину кластера графем
- Примеры:
-
writeln(graphemeStride(" ", 1)); // 1 // A + combing ring above string city = "A\u030Arhus"; size_t first = graphemeStride(city, 0); assert(first == 3); //\u030A has 2 UTF-8 code units writeln(city[0 .. first]); // "A\u030A" writeln(city[first .. $]); // "rhus"
- Grapheme decodeGrapheme(Input)(ref Input inp)
Constraints: if (isInputRange!Input && is(immutable(ElementType!Input) == immutable(dchar))); -
Читает один полный кластер графем из диапазона входных значений dchar
inp.Примеры см. ниже в
Grapheme.- Примечание
- Эта функция изменяет
inp, и поэтомуinpдолжен быть значением-ссылкой.
- auto byGrapheme(Range)(Range range)
Constraints: if (isInputRange!Range && is(immutable(ElementType!Range) == immutable(dchar))); -
Итерация строки по
Grapheme.Полезно для работы со строками, которые должны учитывать графемы.
- См. также:
byCodePoint
- Примеры:
-
import std.algorithm.comparison : equal; import std.range.primitives : walkLength; import std.range : take, drop; auto text = "noe\u0308l"; // noël using e + combining diaeresis assert(text.walkLength == 5); // 5 code points auto gText = text.byGrapheme; assert(gText.walkLength == 4); // 4 graphemes assert(gText.take(3).equal("noe\u0308".byGrapheme)); assert(gText.drop(3).equal("l".byGrapheme));
- auto byCodePoint(Range)(Range range)
Constraints: if (isInputRange!Range && is(immutable(ElementType!Range) == immutable(Grapheme)));
auto byCodePoint(Range)(Range range)
Constraints: if (isInputRange!Range && is(immutable(ElementType!Range) == immutable(dchar))); -
Лениво преобразует диапазон
Graphemeв диапазон кодовых точек.Полезно для преобразования результата в строку после выполнения операций над графемами.
Если на вход подается диапазон кодовых точек, возвращает диапазон с эквивалентными возможностями.
- Примеры:
-
import std.array : array; import std.conv : text; import std.range : retro; string s = "noe\u0308l"; // noël // reverse it and convert the result to a string string reverse = s.byGrapheme .array .retro .byCodePoint .text; assert(reverse == "le\u0308on"); // lëon
- struct Grapheme;
-
Структура, предназначенная для эффективного группирования символов кластера графем.
Graphemeимеет семантику значений, поэтому 2 копииGraphemeвсегда ссылаются на разные объекты. В большинстве реальных сценариевGraphemeпомещается в стеке и избегает накладных расходов на выделение памяти, за исключением довольно длинных кластеров.- См. также:
-
decodeGrapheme,graphemeStride
- this(C)(scope const C[] chars...)
Constraints: if (is(C : dchar));
this(Input)(Input seq)
Constraints: if (!isDynamicArray!Input && isInputRange!Input && is(ElementType!Input : dchar)); -
Конструктор
- const pure nothrow @nogc @trusted dchar opIndex(size_t index);
-
Возвращает кодовую точку по заданному индексу в этом кластере.
- pure nothrow @nogc @trusted void opIndexAssign(dchar ch, size_t index);
-
Записывает кодовую точку
chпо заданному индексу в этом кластере.- Предупреждение
- Использование этого механизма может привести к недействительности кластера графем, см. также
Grapheme.valid.
- Примеры:
-
auto g = Grapheme("A\u0302"); writeln(g[0]); // 'A' assert(g.valid); g[1] = '~'; // ASCII tilda is not a combining mark writeln(g[1]); // '~' assert(!g.valid);
- pure nothrow @nogc @safe SliceOverIndexed!Grapheme opSlice(size_t a, size_t b) return;
pure nothrow @nogc @safe SliceOverIndexed!Grapheme opSlice() return; -
Диапазон произвольного доступа к символам Grapheme.
- Предупреждение
- Становится недействительным при выходе Grapheme из области видимости. Попытка использовать его затем приведет к повреждению памяти.
- const pure nothrow @nogc @property @safe size_t length();
-
Длина кластера графем в кодовых точках.
- ref @trusted auto opOpAssign(string op)(dchar ch);
-
Добавить символ
chк этой графеме.- Предупреждение
- Использование этого механизма может привести к недействительности кластера графем, см. также
valid.
- См. также:
Grapheme.valid
- Примеры:
-
import std.algorithm.comparison : equal; auto g = Grapheme("A"); assert(g.valid); g ~= '\u0301'; assert(g[].equal("A\u0301")); assert(g.valid); g ~= "B"; // not a valid grapheme cluster anymore assert(!g.valid); // still could be useful though assert(g[].equal("A\u0301B"));
- ref auto opOpAssign(string op, Input)(scope Input inp)
Constraints: if (isInputRange!Input && is(ElementType!Input : dchar)); -
Добавить все символы из входного диапазона
inpв эту графему. - @property bool valid()();
-
Истина, если этот объект содержит действительный расширенный кластер графем. Примитивы декодирования этого модуля всегда возвращают действительную
Grapheme.Добавление и прямое манипулирование символами графемы могут сделать ее недействительной. Некоторые приложения могут выбрать использование Grapheme как "малой строки" любых кодовых точек и полностью проигнорировать это свойство.
- int sicmp(S1, S2)(scope S1 r1, scope S2 r2)
Constraints: if (isInputRange!S1 && isSomeChar!(ElementEncodingType!S1) && isInputRange!S2 && isSomeChar!(ElementEncodingType!S2)); -
Выполняет базовое сравнение строк без учета регистра
r1иr2. Эта функция использует более простые правила сравнения, что обеспечивает лучшую производительность, чемicmp. Однако имейте в виду предупреждение ниже.- Параметры:
S1 r1входной диапазон символов S2 r2входной диапазон символов
- Возвращает:
- Значение, которое равно 0, если строки совпадают, < 0, если
r1лексикографически "меньше", чемr2, > 0, еслиr1лексикографически "больше", чемr2
- Предупреждение
- Эта функция обрабатывает только соответствие 1:1 кодовых точек и поэтому не подходит для некоторых алфавитов, таких как немецкий, греческий и некоторых других.
- См. также:
-
icmpstd.algorithm.comparison.cmp
- Примеры:
-
writeln(sicmp("Август", "авгусТ")); // 0 // Greek also works as long as there is no 1:M mapping in sight writeln(sicmp("ΌΎ", "όύ")); // 0 // things like the following won't get matched as equal // Greek small letter iota with dialytika and tonos assert(sicmp("ΐ", "\u03B9\u0308\u0301") != 0); // while icmp has no problem with that writeln(icmp("ΐ", "\u03B9\u0308\u0301")); // 0 writeln(icmp("ΌΎ", "όύ")); // 0
- int icmp(S1, S2)(S1 r1, S2 r2)
Constraints: if (isForwardRange!S1 && isSomeChar!(ElementEncodingType!S1) && isForwardRange!S2 && isSomeChar!(ElementEncodingType!S2)); -
Выполняет сравнение строк без учета регистра
r1иr2. Следует правилам полного преобразования в нижний регистр, в том числе соответствует немецкой ß с "ss" и другим соответствиям 1:N кодовых точек, в отличие отsicmp. Стоимость точной корректностиicmpнесколько ухудшает производительность.- Параметры:
S1 r1диапазон символов S2 r2диапазон символов
- Возвращает:
- Значение, которое равно 0, если строки совпадают, < 0, если
str1лексикографически "меньше", чемstr2, > 0, еслиstr1лексикографически "больше", чемstr2
- См. также:
-
sicmpstd.algorithm.comparison.cmp
- Примеры:
-
writeln(icmp("Rußland", "Russland")); // 0 writeln(icmp("ᾩ -> \u1F70\u03B9", "\u1F61\u03B9 -> ᾲ")); // 0
- Примеры:
- Используя
std.utf.byUTFи его аналоги, можно избежать выделения памяти GC при автоматическом декодировании и исключений, что делаетicmp@safe @nogc nothrow pure.import std.utf : byDchar; writeln(icmp("Rußland".byDchar, "Russland".byDchar)); // 0 writeln(icmp("ᾩ -> \u1F70\u03B9".byDchar, "\u1F61\u03B9 -> ᾲ".byDchar)); // 0
- pure nothrow @nogc @safe ubyte combiningClass(dchar ch);
-
Возвращает комбинирующий класс
ch.- Примеры:
-
// shorten the code alias CC = combiningClass; // combining tilda writeln(CC('\u0303')); // 230 // combining ring below writeln(CC('\u0325')); // 220 // the simple consequence is that "tilda" should be // placed after a "ring below" in a sequence
- enum UnicodeDecomposition: int;
-
Тип разложения символов Юникода.
- Canonical
-
Каноническое разложение. Результат является канонически эквивалентной последовательностью.
- Compatibility
-
Разложение по совместимости. Результат является последовательностью, эквивалентной по совместимости.
- Примечание
- Разложение по совместимости — это **потерянное** преобразование, обычно подходящее только для нечеткого поиска и внутренней обработки.
- pure nothrow @safe dchar compose(dchar first, dchar second);
-
Попытка канонически объединить 2 символа. Возвращает объединенный символ, если они объединяются, и dchar.init в противном случае.
Предполагается, что
firstидет передsecondв исходном тексте, обычно означая, что первый — это стартовый символ.- Примечание
- Силлабические структуры Хангль не обрабатываются этой функцией. См.
composeJamoниже.
- Примеры:
-
writeln(compose('A', '\u0308')); // '\u00C4' writeln(compose('A', 'B')); // dchar.init writeln(compose('C', '\u0301')); // '\u0106' // note that the starter is the first one // thus the following doesn't compose writeln(compose('\u0308', 'A')); // dchar.init
- @safe Grapheme decompose(UnicodeDecomposition decompType = Canonical)(dchar ch);
-
Возвращает полное каноническое (по умолчанию) или разложение по совместимости символа
ch. Если разложение недоступно, возвращаетGraphemeс самимch.- Примечание
- Эта функция также выполняет разложение силлабических структур хангуль согласно стандарту.
- См. также:
-
decomposeHangulдля ограниченной версии, которая учитывает только силлабические структуры хангуль, но не другие разложения.
- Примеры:
-
import std.algorithm.comparison : equal; writeln(compose('A', '\u0308')); // '\u00C4' writeln(compose('A', 'B')); // dchar.init writeln(compose('C', '\u0301')); // '\u0106' // note that the starter is the first one // thus the following doesn't compose writeln(compose('\u0308', 'A')); // dchar.init assert(decompose('Ĉ')[].equal("C\u0302")); assert(decompose('D')[].equal("D")); assert(decompose('\uD4DC')[].equal("\u1111\u1171\u11B7")); assert(decompose!Compatibility('¹')[].equal("1"));
- @safe Grapheme decomposeHangul(dchar ch);
-
Разлагает силлабическую структуру хангуль. Если
chне является составной силлабической структурой, эта функция возвращаетGrapheme, содержащую толькоchкак есть.- Примеры:
-
import std.algorithm.comparison : equal; assert(decomposeHangul('\uD4DB')[].equal("\u1111\u1171\u11B6"));
- pure nothrow @nogc @safe dchar composeJamo(dchar lead, dchar vowel, dchar trailing = (dchar).init);
-
Попытка составить силлабическую структуру хангуль из ведущего согласного (
lead), гласного (vowel) и необязательного конечного согласного (trailing) джамо.При успехе возвращает составленную силлабическую структуру хангуль LV или LVT.
Если какой-либо изleadиvowelне является действительным джамо хангуль соответствующего класса символов, возвращает dchar.init.- Примеры:
-
writeln(composeJamo('\u1111', '\u1171', '\u11B6')); // '\uD4DB' // leaving out T-vowel, or passing any codepoint // that is not trailing consonant composes an LV-syllable writeln(composeJamo('\u1111', '\u1171')); // '\uD4CC' writeln(composeJamo('\u1111', '\u1171', ' ')); // '\uD4CC' writeln(composeJamo('\u1111', 'A')); // dchar.init writeln(composeJamo('A', '\u1171')); // dchar.init
- enum NormalizationForm: int;
-
Тип перечисления для форм нормализации, передаваемый в качестве шаблонного параметра для функций, таких как
normalize. -
NFC
NFD
NFKC
NFKD -
Сокращённые псевдонимы значений, указывающих формы нормализации.
- inout(C)[] normalize(NormalizationForm norm = NFC, C)(inout(C)[] input);
-
Возвращает
inputстроку, нормализованную до выбранной формы. По умолчанию используется форма C.Дополнительную информацию о формах нормализации см. в разделе нормализации.
- Примечание
- В тех случаях, когда интересующая строка уже нормализована, она возвращается без изменений, и выделение памяти не происходит.
- Примеры:
-
// any encoding works wstring greet = "Hello world"; assert(normalize(greet) is greet); // the same exact slice // An example of a character with all 4 forms being different: // Greek upsilon with acute and hook symbol (code point 0x03D3) writeln(normalize!NFC("ϓ")); // "\u03D3" writeln(normalize!NFD("ϓ")); // "\u03D2\u0301" writeln(normalize!NFKC("ϓ")); // "\u038E" writeln(normalize!NFKD("ϓ")); // "\u03A5\u0301"
- bool allowedIn(NormalizationForm norm)(dchar ch);
-
Проверяет, разрешен ли dchar
chвсегда (Quick_Check=YES) в форме нормализацииnorm.- Примеры:
-
// e.g. Cyrillic is always allowed, so is ASCII assert(allowedIn!NFC('я')); assert(allowedIn!NFD('я')); assert(allowedIn!NFKC('я')); assert(allowedIn!NFKD('я')); assert(allowedIn!NFC('Z'));
- pure nothrow @nogc @safe bool isWhite(dchar c);
-
Является ли
cсимволом Unicode пробела символа. (общая категория Unicode: часть C0 (табуляция, вертикальная табуляция, подача формы, возврат каретки и перевод строки), Zs, Zl, Zp и NEL (U+0085)). - pure nothrow @nogc @safe bool isLower(dchar c);
-
Возвращает значение, показывающее, является ли
cсимволом Unicode строчной буквы символа. - pure nothrow @nogc @safe bool isUpper(dchar c);
-
Возвращает значение, показывающее, является ли
cсимволом Unicode заглавной буквы символа. - auto asLowerCase(Range)(Range str)
Constraints: if (isInputRange!Range && isSomeChar!(ElementEncodingType!Range) && !isConvertibleToString!Range);
auto asUpperCase(Range)(Range str)
Constraints: if (isInputRange!Range && isSomeChar!(ElementEncodingType!Range) && !isConvertibleToString!Range); -
Преобразование диапазона ввода или строки в верхний или нижний регистр.
Не выделяет память. Символы в формате UTF-8 или UTF-16, которые не могут быть декодированы, обрабатываются как
std.utf.replacementDchar.- Параметры:
Диапазон strстрока или диапазон символов
- Возвращает:
- диапазон ввода
dchar
- См. также:
-
toUpper,toLower
- Примеры:
-
import std.algorithm.comparison : equal; assert("hEllo".asUpperCase.equal("HELLO"));
- auto asCapitalized(Range)(Range str)
Constraints: if (isInputRange!Range && isSomeChar!(ElementEncodingType!Range) && !isConvertibleToString!Range); -
Преобразование диапазона ввода или строки в заглавные буквы, что означает преобразование первого символа в верхний регистр, а последующих – в нижний.
Не выделяет память. Символы в формате UTF-8 или UTF-16, которые не могут быть декодированы, обрабатываются как
std.utf.replacementDchar.- Параметры:
Диапазон strстрока или диапазон символов
- Возвращает:
- диапазон ввода dchar
- См. также:
-
toUpper,toLowerasUpperCase,asLowerCase
- Примеры:
-
import std.algorithm.comparison : equal; assert("hEllo".asCapitalized.equal("Hello"));
- pure @trusted void toLowerInPlace(C)(ref C[] s)
Constraints: if (is(C == char) || is(C == wchar) || is(C == dchar)); -
Преобразует
sв нижний регистр (путем выполнения отображения Unicode в нижний регистр) на месте. Для некоторых символов длина строки может увеличиться после преобразования, в этом случае функция перераспределяет память ровно один раз. Еслиsне содержит символов верхнего регистра, тоsостается без изменений. - pure @trusted void toUpperInPlace(C)(ref C[] s)
Constraints: if (is(C == char) || is(C == wchar) || is(C == dchar)); -
Преобразует
sв верхний регистр (путем выполнения отображения Unicode в верхний регистр) на месте. Для некоторых символов длина строки может увеличиться после преобразования, в этом случае функция перераспределяет память ровно один раз. Еслиsне содержит символов нижнего регистра, тоsостается без изменений. - pure nothrow @nogc @safe dchar toLower(dchar c);
-
Если
cявляется символом Unicode верхнего регистра символа, то возвращается его эквивалент в нижнем регистре. В противном случае возвращаетсяc.- Предупреждение
- некоторые алфавиты, такие как немецкий и греческий, не имеют взаимно однозначного отображения верхнего и нижнего регистра. Используйте перегрузку toLower, которая принимает всю строку.
- ElementEncodingType!S[] toLower(S)(S s)
Constraints: if (isSomeString!S || isRandomAccessRange!S && hasLength!S && hasSlicing!S && isSomeChar!(ElementType!S)); -
Создаёт новый массив, идентичный
s, за исключением того, что все его символы преобразуются в нижний регистр (путем выполнения отображения Unicode в нижний регистр). Если ни один изsсимволов не был изменён, то возвращаетсяsсамо по себе, еслиsявляется типом наподобиеstring.- Параметры:
S sДиапазон случайного доступа символов
- Возвращает:
- Массив с тем же типом элементов, что и
s.
- pure nothrow @nogc @safe dchar toUpper(dchar c);
-
Если
cявляется символом Unicode нижнего регистра символа, то возвращается его эквивалент в верхнем регистре. В противном случае возвращаетсяc.- Предупреждение
- некоторые алфавиты, такие как немецкий и греческий, не имеют взаимно однозначного отображения верхнего и нижнего регистра. Используйте перегрузку toUpper, которая принимает всю строку вместо этого.
std.algorithm.iteration.mapдля создания алгоритма, который может преобразовывать диапазон символов в верхний регистр без выделения памяти. Строка затем может быть создана с помощьюstd.algorithm.mutation.copyдля отправки вstd.array.appender.- Примеры:
-
import std.algorithm.iteration : map; import std.algorithm.mutation : copy; import std.array : appender; auto abuf = appender!(char[])(); "hello".map!toUpper.copy(abuf); writeln(abuf.data); // "HELLO"
- ElementEncodingType!S[] toUpper(S)(S s)
Constraints: if (isSomeString!S || isRandomAccessRange!S && hasLength!S && hasSlicing!S && isSomeChar!(ElementType!S)); -
Выделяет новый массив, идентичный
s, за исключением того, что все его символы преобразуются в верхний регистр (путем выполнения отображения Unicode в верхний регистр). Если ни один изsсимволов не был изменён, то возвращаетсяsсамо по себе, еслиsявляется типом наподобиеstring.- Параметры:
S sДиапазон случайного доступа символов
- Возвращает:
- Новый массив с тем же типом элементов, что и
s.
- pure nothrow @nogc @safe bool isAlpha(dchar c);
-
Возвращает значение, показывающее, является ли
cбуквенным символом Unicode символа (общая категория Unicode: Буквенный). - pure nothrow @nogc @safe bool isMark(dchar c);
-
Возвращает значение, показывающее, является ли
cсимволом-меткой Unicode (общая категория Unicode: Mn, Me, Mc). - pure nothrow @nogc @safe bool isNumber(dchar c);
-
Возвращает значение, показывающее, является ли
cчисловым символом Unicode символа (общая категория Unicode: Nd, Nl, No). - pure nothrow @nogc @safe bool isAlphaNum(dchar c);
-
Возвращает значение, показывающее, является ли
cбуквенным символом Unicode символа или числом. (общая категория Unicode: Буквенный, Nd, Nl, No).- Параметры:
dchar cлюбой символ Unicode
- Возвращает:
-
true, если символ принадлежит категориям Unicode Alphabetic, Nd, Nl или No
- pure nothrow @nogc @safe bool isPunctuation(dchar c);
-
Возвращает значение, показывающее, является ли
cсимволом пунктуации Unicode символа (общая категория Unicode: Pd, Ps, Pe, Pc, Po, Pi, Pf). - pure nothrow @nogc @safe bool isSymbol(dchar c);
-
Возвращает значение, показывающее, является ли
cсимволом Unicode символа (общая категория Unicode: Sm, Sc, Sk, So). - pure nothrow @nogc @safe bool isSpace(dchar c);
-
Возвращает значение, показывающее, является ли
cсимволом пробела Unicode символа (общая категория Unicode: Zs)- Примечание
- Это не включает '\n', '\r', '\t' и другие символы, не являющиеся пробелами символа. Для более распространенных менее строгих семантик см.
isWhite.
- pure nothrow @nogc @safe bool isGraphical(dchar c);
-
Возвращает, является ли
cграфическим символом Юникода (общая категория Юникода: L, M, N, P, S, Zs). - pure nothrow @nogc @safe bool isControl(dchar c);
-
Возвращает, является ли
cуправляющим символом Юникода (общая категория Юникода: Cc). - pure nothrow @nogc @safe bool isFormat(dchar c);
-
Возвращает, является ли
cсимволом форматирования Юникода (общая категория Юникода: Cf). - pure nothrow @nogc @safe bool isPrivateUse(dchar c);
-
Возвращает, является ли
cкодовой точкой Юникода для частного использования (общая категория Юникода: Co). - pure nothrow @nogc @safe bool isSurrogate(dchar c);
-
Возвращает, является ли
cкодовой точкой Юникода, являющейся суррогатом (общая категория Юникода: Cs). - pure nothrow @nogc @safe bool isSurrogateHi(dchar c);
-
Возвращает, является ли
cстаршим суррогатом Юникода (ведущий суррогат). - pure nothrow @nogc @safe bool isSurrogateLo(dchar c);
-
Возвращает, является ли
cмладшим суррогатом Юникода (завершающий суррогат). - pure nothrow @nogc @safe bool isNonCharacter(dchar c);
-
Возвращает, является ли
cсимволом Юникода, не являющимся символом, т. е. кодовой точкой без назначенного абстрактного символа. (общая категория Юникода: Cn)
© 1999–2021 The D Language Foundation
Licensed under the Boost License 1.0.
https://dlang.org/phobos/std_uni.html