Reference index · Official Lua 5.2 string library · C Lua 5.2.4 source · Implementation
Install with state.OpenStringLibrary(). String method calls such as s:sub(2) use this library through the string metatable.
The central difference is representation: operations use UTF-16 code units by default and bytes in LuaStringMode.Bytes. This makes default-mode operations convenient for .NET strings; byte mode preserves Lua's binary-string model. See String modes. Indices are 1-based; negative substring indices count from the end.
| API / official reference | Inputs and result | Lua-CSharp implementation notes and differences |
|---|---|---|
string.byte(s [, i [, j]]) |
Returns the numeric units in the inclusive range, defaulting to the first unit. | Default mode returns UTF-16 code-unit values, including surrogate values. Byte mode returns 0–255. The managed string representation determines the units. |
string.char(...) |
Constructs a string from numeric character values. | Byte mode requires 0–255, as Lua byte strings do. Default mode casts the integer values to UTF-16 char, rather than enforcing a byte range; use ordinary text or byte mode according to the intended data. |
string.dump(f) |
Serializes a Lua function's prototype as a raw binary string. Captured values are not serialized. C# functions cannot be dumped. | Available in both string modes; the result always holds raw byte values. See dumping and loading. |
string.find(s, pattern [, init [, plain]]) |
Returns match start/end and captures, or nil. plain selects literal substring search. |
Positions use the state's string units. Pattern character classes use the rules below; plain search uses ordinal string matching. |
string.format(format, ...) |
Formats values using Lua's printf-style conversions, including %s, %q, integer, floating-point, and hexadecimal floating-point conversions. |
Width/precision count managed string units. %c constructs a UTF-16 unit in default mode and masks to one byte in byte mode. Numeric text and special values follow NumberFormat where applicable. Integer formatting uses 64-bit signed/unsigned ranges; these can differ from a C Lua build's configured integer formatting width. See format details. |
string.gmatch(s, pattern) |
Returns an iterator over captures, or whole matches when there are no captures. | Positions and classes follow the selected string mode. |
string.gsub(s, pattern, replacement [, n]) |
Returns the replaced string and match count. Replacement may be text, a number, a table, or a function. False/nil replacement results retain the matched text. | Numeric replacements use NumberFormat. Table __index and replacement callbacks can await C# work but cannot Lua-yield through this library call. |
string.len(s) |
Returns the string length, including embedded zero units. | Counts UTF-16 units by default and bytes in byte mode; neither counts Unicode grapheme clusters. |
string.lower(s) |
Converts uppercase units to lowercase. | Default mode uses .NET current-culture Unicode casing through String.ToLower; byte mode changes ASCII A–Z only. Native Lua uses its C locale. os.setlocale does not set .NET's current culture. |
string.match(s, pattern [, init]) |
Returns captures or the whole match, or nil. | Positions and classes follow the selected string mode. |
string.rep(s, n [, sep]) |
Repeats s, inserting sep between copies. Non-positive counts produce an empty string. |
Counts are truncated as in Lua 5.2; resulting lengths are bounded by .NET string/int capacity. |
string.reverse(s) |
Reverses the sequence of string units. | Default mode can split/reverse surrogate pairs; byte mode reverses bytes and can split UTF-8 sequences. This operation is not Unicode text-element reversal. |
string.sub(s, i [, j]) |
Returns the inclusive slice, with j defaulting to the last unit. |
Slices UTF-16 units or bytes according to the mode, including partial surrogate pairs/UTF-8 sequences. |
string.upper(s) |
Converts lowercase units to uppercase. | Default mode uses .NET current-culture Unicode casing through String.ToUpper; byte mode changes ASCII a–z only. The host's .NET culture, rather than the process C locale, controls default-mode casing. |
Official pattern syntax applies: Lua patterns are not .NET regular expressions. Captures, position captures (), balanced matches %b, frontier patterns %f, anchors, and Lua repetition operators are handled by the Lua pattern matcher.
Default-mode letter, digit, case, control, whitespace, and graphical classes use .NET character classification. %p uses ASCII punctuation ranges, %x uses ASCII hexadecimal digits, and %z matches NUL. In byte mode, all classes use ASCII C-locale rules. Thus non-ASCII letters may match %a in default mode but not in byte mode. os.setlocale does not change these rules. Pattern recursion and capture counts are bounded by the managed matcher.
Managed %s formatting preserves embedded NUL units. For example, string.format('%5s', string.char(97, 0, 98)) produces two spaces followed by a, NUL, and b. C Lua 5.2.4 passes this short string to C sprintf, which stops at the NUL and produces four spaces followed by a. C Lua has a separate path for long strings without precision, so its %s NUL behavior is not uniform across inputs.
local bytes = string.dump(function() return 42 end)
local f = assert(load(bytes, 'saved', 'b'))
assert(f() == 42)Use byte-mode streams when saving bytes from Lua. In C#, use LuaByteString.ToBytes to extract its raw bytes. A UTF-16 stream encodes characters as UTF-8 and can corrupt arbitrary binary strings even if opened with wb.
Chunks use the C Lua 5.2 layout, with the architecture/number sizes recorded in their header. Do not assume portability across different Lua versions or incompatible binary layouts. Older Lua-CSharp chunks generated with the previous incorrect header/tag layout must be regenerated from source. Prototype.StringMode preserves the representation of constants during dumping.
Lua 5.3/5.4 additions such as string.pack, string.unpack, and string.packsize are not part of this Lua 5.2 library.