Столкнулся с проблемой отсутствия простых операций со строками, содержащими символы юникода (например, русские буквы), в стандартной библиотеке Zig.
Конкретно, требовалось привести строку в нижний регистр. И оказалось, впрочем ожидаемо, что методы модуля std.ascii не годятся для этого, прямо совсем. Ибо константа lowercase содержит только латинские символы.
А в модуле std.unicode в принципе нет методов, для реализации приведения к нижнему/верхнему регистру символов. В итоге пришлось городить небольшой костыль:
// Кастомное преобразование строки в нижний регистр, с поддержкой // обработки русских символов, латиницы и акцентированных знаков. fn toLowerCustom(allocator: Allocator, str: []const u8) ![]const u8 { var result = std.ArrayList(u8).init(allocator); var iter = std.unicode.Utf8Iterator{ .bytes = str, .i = 0 }; while (iter.nextCodepoint()) |cp| { const lower = blk: { // Русские символы if (cp >= 'А' and cp <= 'Я') break :blk cp + ('а' - 'А'); if (cp == 'Ё') break :blk 'ё'; // Базовые латинские символы if (cp >= 'A' and cp <= 'Z') break :blk cp + 32; // Обработка акцентированных символов break :blk switch (cp) { 0xC0...0xD6 => cp + 32, // À-Ö → à-ö 0xD8...0xDE => cp + 32, // Ø-Þ → ø-þ 0x100...0x17F => handleLatinExtended(cp), else => cp, }; }; var buf: [4]u8 = undefined; const len = std.unicode.utf8Encode(lower, &buf) catch unreachable; try result.appendSlice(buf[0..len]); } return result.toOwnedSlice(); }
Знаю про существование библиотек для работы со строками на Zig, но ни одна не завелась, да и ради одного метода, тащить всю библиотеку, ИМХО, избыточно. Возможно, что я что-то пропустил и есть проверенные готовые решения?
