Strings and Text
11.1 Strings Are Byte Slices
String literals have type *const [N:0]u8 and coerce to []const u8 (the idiomatic string type).
Zig has no dedicated string type. Strings are UTF-8 bytes by convention.
const s: []const u8 = "Hello, Zig!";
std.debug.print("{s} len={d} first={c}\n", .{ s, s.len, s[0] });
for (s) |byte| _ = byte; // iterate bytes
if (std.mem.eql(u8, s, "Hello, Zig!")) {} // compare11.2 Splitting, Tokenizing, Trimming
const mem = std.mem;
var it = mem.splitScalar(u8, "a,b,,c", ','); // yields "a", "b", "", "c"
while (it.next()) |part| std.debug.print("[{s}]", .{part});
var tok = mem.tokenizeAny(u8, " hello world ", " "); // skips empty pieces
while (tok.next()) |w| std.debug.print("{s}\n", .{w});
var seq = mem.splitSequence(u8, "a::b::c", "::");
_ = seq;
const trimmed = mem.trim(u8, " hi ", " ");
const t2 = mem.trimLeft(u8, "xxhi", "x");
_ = .{ trimmed, t2 };
var lines = mem.splitScalar(u8, text, '\n'); // line iteration
_ = lines;11.3 Parsing and Formatting Numbers
const n = try std.fmt.parseInt(i32, "-42", 10);
const h = try std.fmt.parseInt(u32, "ff", 16);
const f = try std.fmt.parseFloat(f64, "3.14");
var buf: [64]u8 = undefined;
const out = try std.fmt.bufPrint(&buf, "{d}-{s}", .{ n, "x" }); // into a stack buffer
const heap = try std.fmt.allocPrint(allocator, "{d:0>5}", .{h}); // heap-allocated (caller frees)
defer allocator.free(heap);
_ = .{ f, out };11.4 Building Strings
var list: std.ArrayList(u8) = .empty; // 0.15: unmanaged by default
defer list.deinit(allocator);
try list.appendSlice(allocator, "Hello");
try list.append(allocator, ',');
try list.print(allocator, " {s}!", .{"World"});
const owned = try list.toOwnedSlice(allocator); // transfer ownership
defer allocator.free(owned);
const joined = try std.mem.join(allocator, ", ", &.{ "a", "b", "c" });
defer allocator.free(joined);
const concat = try std.mem.concat(allocator, u8, &.{ "foo", "bar" });
defer allocator.free(concat);
const replaced = try std.mem.replaceOwned(u8, allocator, "a-b-c", "-", "+");
defer allocator.free(replaced);
const dup = try allocator.dupe(u8, "copy me");
defer allocator.free(dup);11.5 ASCII and Unicode
For full Unicode (grapheme clusters, normalization, case folding), use packages such as zg (ziglyph's successor).
const ascii = std.ascii;
_ = ascii.isDigit('5');
_ = ascii.isAlphabetic('a');
_ = ascii.toUpper('a');
var upbuf: [16]u8 = undefined;
_ = ascii.upperString(&upbuf, "hello");
_ = ascii.eqlIgnoreCase("Zig", "ZIG");
const unicode = std.unicode;
const text = "héllo 🌍";
const view = try unicode.Utf8View.init(text);
var cps = view.iterator();
while (cps.nextCodepoint()) |cp| std.debug.print("U+{X} ", .{cp});
_ = try unicode.utf8CountCodepoints(text);
_ = unicode.utf8ValidateSlice(text);
var enc: [4]u8 = undefined;
_ = try unicode.utf8Encode('🌍', &enc);