CodeRigor

FREE LESSON

Strings, byte boundaries & Lua patterns

Use anchored Lua patterns, explicit conversions and byte-aware string operations for a small record format.

Before this lesson, complete lua-tables.

This course runs standard Lua 5.5 with its standard library. Game engines, LuaJIT and embedded host APIs are outside this sequence.

Lua strings are immutable byte sequences. The # operator counts bytes, and string indexing and slicing use byte positions. That is suitable for this lab's ASCII record grammar. It is not a Unicode character-counting or grapheme-boundary interface. Use UTF-8 facilities or an appropriate text library when those properties matter.

Match the whole record
start / 3
Match the whole record

Apply the contract

Lua patterns provide a small matching language rather than a full regular-expression engine. Parenthesized captures return selected substrings. Anchors ^ and $ require the entire record to match, so a valid-looking substring inside junk cannot pass. Escape a special pattern character with %, not a regular-expression backslash. The optional minus in the score pattern uses -? outside a character class; the allowed name characters are kept in a separate class.

Capture then convert
start / 3
Capture then convert
Lua
local name,score=("model=alpha;score=-7"):match("^model=([%w_%-]+);score=(%-?%d+)$")
print(name,tonumber(score))
print(("a.b"):find(".",1,true))
print(#"abc",utf8.len("abc"))

Reason about the edge cases

Matching produces strings. Convert the captured score with tonumber after the grammar succeeds, then return both the name and numeric score. If the whole record does not match, return nil. Do not accept a decimal fraction, a plus sign or a trailing suffix merely because tonumber could interpret some broader input. The lab specifies ASCII names and integer text so the intended boundary is concrete. Read the pattern from left to right and test each rejection rule separately: a missing field, empty name, extra field and suffix should all fail without depending on table iteration or locale-sensitive ordering.

Bytes and text
start / 3
Bytes and text

Practice

Implement M.parse(line) for exactly model=NAME;score=INTEGER. NAME is nonempty ASCII letters, digits, underscore or hyphen; INTEGER is an optional minus followed by digits, within one million in magnitude. Return name and the numeric score. Reject leading/trailing text, decimals, empty names or malformed fields by returning nil. This is a Lua pattern exercise, not a regular-expression engine.

Run sample starts again from the first public fixture and grants no mastery evidence. Submit checks all fixtures, including edge cases. Read the specification before editing; the bug and fill phases share the build’s contract. Flashcards reinforce recall on a separate schedule.

Watch & read

Free lectures, talks and readings that cover this skill from another angle. All resources →

The first part introduces Lua through its language designer. The authored lesson and Lua 5.5 manual cover the exact APIs and advanced details in this lab.