String(3)
π String(3) β Strings π
OCaml library manual Β· String(3) Β· part 1, bestie β¨
πΈ NAME πΈ
String β Strings. That's the whole vibe: this is the module page for OCaml strings, and it is long, so buckle up π
π§© Module π§©
Module String : sig end
π Documentation π
Okay so this is the String module, and here's the tea: a string s of length n is an indexable and immutable sequence of n bytes. For historical reasons these bytes are referred to as characters. Yes, bytes are getting called characters, we don't make the rules π
The semantics of string functions is defined in terms of indices and positions. These are depicted and described as follows.
positions 0 1 2 3 4 n-1 n +---+---+---+---+ +-----+
indices | 0 | 1 | 2 | 3 | ... | n-1 | +---+---+---+---+ +-----+
-An index i of s is an integer in the range [ 0 ; n-1 ]. It represents the i th byte (character) of s which can be accessed using the constant time string indexing operator s.[i] .
-A position i of s is an integer in the range [ 0 ; n ]. It represents either the point at the beginning of the string, or the point between two indices, or the point at the end of the string. The i th byte index is between position i and i+1 .
Two integers start and len are said to define a valid substring of s if len >= 0 and start, start+len are positions of s .
Unicode text. Strings being arbitrary sequences of bytes, they can hold any kind of textual encoding. However the recommended encoding for storing Unicode text in OCaml strings is UTF-8. This is the encoding used by Unicode escapes in string literals. For example the string "\u{1F42B}" is the UTF-8 encoding of the Unicode character U+1F42B π¦
Past mutability. Before OCaml 4.02, strings used to be modifiable in place like Bytes.t mutable sequences of bytes. OCaml 4 had various compiler flags and configuration options to support the transition period from mutable to immutable strings. Those options are no longer available, and strings are now always immutable. Periodt, they stay put π
The labeled version of this module can be used as described in the StdLabels module.
π§΅ Strings π§΅
type t = stringβ the type for strings. That's it, that's the type πval make : int -> char -> stringβmake n cis a string of lengthnwith each index holding the characterc. RaisesInvalid_argumentifn < 0orn > Sys.max_string_length.val init : int -> (int -> char) -> stringβinit n fis a string of lengthnwith indexiholding the characterf i(called in increasing index order). Since 4.02. RaisesInvalid_argumentifn < 0orn > Sys.max_string_length.val empty : stringβ the empty string. Since 4.13 β¨val length : string -> intβlength sis the length (number of bytes/characters) ofs.val get : string -> int -> charβget s iis the character at indexiins. This is the same as writings.[i]. RaisesInvalid_argumentifinot an index ofs.val of_char : char -> stringβof_char ciscas a string. Since 5.5 πval of_bytes : bytes -> stringβ Return a new string that contains the same bytes as the given byte sequence. Since 4.13 πval to_bytes : string -> bytesβ Return a new byte sequence that contains the same bytes as the given string. Since 4.13 πΈval blit : string -> int -> bytes -> int -> int -> unitβ Same asBytes.blit_stringwhich should be preferred. Lowkey just use theBytesone, bestie π
π Concatenating π
Note. The (^) binary operator concatenates two strings.
val concat : string -> string list -> stringβconcat sep ssconcatenates the list of stringsss, inserting the separator stringsepbetween each. RaisesInvalid_argumentif the result is longer thanSys.max_string_lengthbytes.val cat : string -> string -> stringβcat s1 s2concatenatess1ands2(s1 ^ s2). Since 4.13. RaisesInvalid_argumentif the result is longer thanSys.max_string_lengthbytes.
π Predicates and comparisons π
val equal : t -> t -> boolβequal s0 s1istrueif and only ifs0ands1are character-wise equal. Since 4.03 (4.05 inStringLabels) β¨val compare : t -> t -> intβcompare s0 s1sortss0ands1in lexicographical order.comparebehaves likecompareon strings but may be more efficient.val is_empty : string -> boolβis_empty sistrueif and only ifsis an empty string. Since 5.5 π«Άval starts_with : prefix:string -> string -> boolβstarts_with ~prefix sistrueif and only ifsstarts withprefix. Since 4.13 πval ends_with : suffix:string -> string -> boolβends_with ~suffix sistrueif and only ifsends withsuffix. Since 4.13 πval includes : affix:string -> string -> boolβincludes affix sistrueif and only ifaffixoccurs ins. Since 5.5. Note. To test the sameaffixstring multiple times, partially applying the~affixargument and using the resulting function repeatedly is more efficient. iykyk π§val contains_from : string -> int -> char -> boolβcontains_from s start cistrueif and only ifcappears insafter positionstart. RaisesInvalid_argumentifstartis not a valid position ins.val rcontains_from : string -> int -> char -> boolβrcontains_from s stop cistrueif and only ifcappears insbefore positionstop+1. RaisesInvalid_argumentifstop < 0orstop+1is not a valid position ins.val contains : string -> char -> boolβcontains s cisString.contains_from s 0 c.
βοΈ Extracting substrings βοΈ
val sub : string -> int -> int -> stringβsub s pos lenis a string of lengthlen, containing the substring ofsthat starts at positionposand has lengthlen. RaisesInvalid_argumentifposandlendo not designate a valid substring ofs.
πͺ Splitting strings πͺ
π Splitting with magnitudes π
val take_first : int -> string -> stringβtake_first n sare the firstnbytes ofs. This issifn >= length sand""ifn <= 0. Since 5.5 πval take_last : int -> string -> stringβtake_last n sare the lastnbytes ofs. This issifn >= length sand""ifn <= 0. Since 5.5 πval drop_first : int -> string -> stringβdrop_first n sisswithout the firstnbytes ofs. This is""ifn >= length sandsifn <= 0. Since 5.5 πΈval drop_last : int -> string -> stringβdrop_last n sisswithout the lastnbytes ofs. This is""ifn >= length sandsifn <= 0. Since 5.5 πΈval cut_first : int -> string -> string * stringβcut_first n vis(take_first n v, drop_first n v). Since 5.5 πval cut_last : int -> string -> string * stringβcut_last n vis(drop_last n v, take_last n v). Since 5.5 π
π¦ Splitting with predicates π¦
val take_first_while : (char -> bool) -> string -> stringβtake_first_while p sis the first consecutive bytes ofssatisfying the predicatep. Since 5.5 β¨val take_last_while : (char -> bool) -> string -> stringβtake_last_while p sis the last consecutive bytes ofssatisfying the predicatep. Since 5.5 β¨val drop_first_while : (char -> bool) -> string -> stringβdrop_first_while p sisswithout the first consecutive bytes ofssatisfying the predicatep. Since 5.5 πval drop_last_while : (char -> bool) -> string -> stringβdrop_last_while p sisswithout the last consecutive bytes ofssatisfying the predicatep. Since 5.5 πval cut_first_while : (char -> bool) -> string -> string * stringβcut_first_while p sis(take_first_while p s, drop_first_while p s). Since 5.5 πval cut_last_while : (char -> bool) -> string -> string * stringβcut_last_while p sis(drop_last_while p s, take_last_while p s). Since 5.5 π
π§ Splitting with separators π§
Note. To split the samesepstring multiple times, partially applying the~separgument of these functions and using the resulting function repeatedly is more efficient.
val split_first : sep:string -> string -> (string * string) optionβsplit_first sep sis the pairSome (left, right)made of the two (possibly empty) substrings ofsthat are delimited by the first match of the separatorsepinsorNoneifsepcan't be found. Search forsepstarts at position0and usesString.find_first. Ifsepis"", this isSome ("", s). The invariantconcat sep [left; right] = sholds. Since 5.5 πval split_last : sep:string -> string -> (string * string) optionβsplit_last sep sis the pairSome (left, right)made of the two (possibly empty) substrings ofsthat are delimited by the last match of the separatorsepinsorNoneifsepcan't be found. Search forsepstarts at positionlength sand usesString.find_last. Ifsepis"", this isSome (s, ""). The invariantconcat sep [left; right] = sholds. Since 5.5 πval split_all : sep:string -> ?drop:(string -> bool) -> string -> string listβsplit_all sep sis the list of all substrings ofsthat are delimited by non-overlapping matches of the separatorsepor the list[s]ifsepcan't be found. Search forsepstarts at position0in increasing indexing order and usesString.find_all. Substringssubfor whichdrop subistrueare not included in the result.dropdefaults toFun.const false. Ifsepis"", this is[""; c0; ...; cn; ""]withcithe stringof_char s.[i]. The invariantconcat sep (split_all sep s) = sholds. Since 5.5 πval rsplit_all : sep:string -> ?drop:(string -> bool) -> string -> string listβrsplit_all sep sis the list of all substrings ofsthat are delimited by non-overlapping matches of the separatorsepor[s]ifsepcan't be found. Search forsepstarts at positionlength sin decreasing indexing order and usesString.rfind_all. Substringssubfor whichdrop subistrueare not included in the result.dropdefaults toFun.const false. Ifsepis"", this is[""; c0; ...; cn; ""]withcithe stringof_char s.[i]. The invariantconcat sep (rsplit_all sep s) = sholds. Since 5.5 πval split_on_char : char -> string -> string listβsplit_on_char sep sis the list of all (possibly empty) substrings ofsthat are delimited by the charactersep. Ifsis empty, the result is the singleton list[""]. The function's result is specified by the following invariants:
-The list is not empty.
-Concatenating its elements using sep as a separator returns a string equal to the input ( concat (make 1 sep) (split_on_char sep s) = s ).
-No string in the result contains the sep character.
Since 4.04 (4.05 in StringLabels) π
π¦ Transforming π¦
val map : (char -> char) -> string -> stringβmap f sis the string resulting from applyingfto all the characters ofsin increasing order. Since 4.00 β¨val mapi : (int -> char -> char) -> string -> stringβmapi f sis likeString.mapbut the index of the character is also passed tof. Since 4.02 πval fold_left : ('acc -> char -> 'acc) -> 'acc -> string -> 'accβfold_left f x scomputesf (... (f (f x s.[0]) s.[1]) ...) s.[n-1], wherenis the length of the strings. Since 4.13 πval fold_right : (char -> 'acc -> 'acc) -> string -> 'acc -> 'accβfold_right f s xcomputesf s.[0] (f s.[1] ( ... (f s.[n-1] x) ...)), where n is the length of the strings.
β¨ Since 4.13
val for_all : (char -> bool) -> string -> boolβfor_all p schecks if all characters inssatisfy the predicatep.
β¨ Since 4.13
val exists : (char -> bool) -> string -> boolβexists p schecks if at least one character ofssatisfies the predicatep.
β¨ Since 4.13
val trim : string -> stringβtrim sisswithout leading and trailing whitespace, bestie. And "whitespace" here literally means:' ','\x0C'(form feed),'\n','\r', and'\t'. That's the whole list, no extras, periodt.
β¨ Since 4.00
val escaped : string -> stringβescaped sissbut with special characters represented by escape sequences, following the lexical conventions of OCaml. Iconic behavior honestly.
Every character outside the US-ASCII printable range [0x20;0x7E] gets escaped, plus backslash (0x5C) and double-quote (0x22).
The function Scanf.unescaped is a left inverse of escaped, i.e. Scanf.unescaped (escaped s) = s for any string s (unless escaped s fails). Cute lil inverse relationship π
- Raises
Invalid_argumentif the result is longer thanSys.max_string_lengthbytes. π
val uppercase_ascii : string -> stringβuppercase_ascii sisswith all lowercase letters translated to uppercase, using the US-ASCII character set.
β¨ Since 4.03 (4.05 in StringLabels)
val lowercase_ascii : string -> stringβlowercase_ascii sisswith all uppercase letters translated to lowercase, using the US-ASCII character set.
β¨ Since 4.03 (4.05 in StringLabels)
val capitalize_ascii : string -> stringβcapitalize_ascii sisswith the first character set to uppercase, using the US-ASCII character set.
β¨ Since 4.03 (4.05 in StringLabels)
val uncapitalize_ascii : string -> stringβuncapitalize_ascii sisswith the first character set to lowercase, using the US-ASCII character set.
β¨ Since 4.03 (4.05 in StringLabels)
πΆββοΈ Traversing
val iter : (char -> unit) -> string -> unitβiter f sapplies functionfin turn to all the characters ofs. It is equivalent tof s.[0]; f s.[1]; ...; f s.[length s - 1]; (). Like walking the whole string, girly pop, one char at a time.val iteri : (int -> char -> unit) -> string -> unitβiteriis likeString.iter, but the function is also given the corresponding character index. Two-for-one deal, we love to see it π«Ά
β¨ Since 4.00
π Finding indices
val find_first_index : (char -> bool) -> ?start:int -> string -> int optionβfind_first_index p start sis the index of the first character ofsthat satisfies predicatepat or after the index or positionstart(defaults to0).
If start is length s, the result is always None. So don't come for her when she returns None, that's correct π
β¨ Since 5.5
- Raises
Invalid_argumentifstartis not a valid position ofs.
val find_last_index : (char -> bool) -> ?start:int -> string -> int optionβfind_last_index p start sis the index of the last character ofsthat satisfies predicatepat or before the index or positionstart(defaults tolength s). Backwards search era πΈ
β¨ Since 5.5
- Raises
Invalid_argumentifstartis not a valid position ofs.
val index_from : string -> int -> char -> intβindex_from s i cis the index of the first occurrence ofcinsafter positioni.- Raises
Not_foundifcdoes not occur insafter positioni. - Raises
Invalid_argumentifiis not a valid position ins.
- Raises
val index_from_opt : string -> int -> char -> int optionβindex_from_opt s i cis the index of the first occurrence ofcinsafter positioni(if any). The_optversion so you don't get yeeted by an exception, we stan π
β¨ Since 4.05
- Raises
Invalid_argumentifiis not a valid position ins.
val rindex_from : string -> int -> char -> intβrindex_from s i cis the index of the last occurrence ofcinsbefore positioni+1. Note thei+1, that's not a typo, keep it exactly like that bestie.- Raises
Not_foundifcdoes not occur insbefore positioni+1. - Raises
Invalid_argumentifi+1is not a valid position ins.
- Raises
val rindex_from_opt : string -> int -> char -> int optionβrindex_from_opt s i cis the index of the last occurrence ofcinsbefore positioni+1(if any).
β¨ Since 4.05
- Raises
Invalid_argumentifi+1is not a valid position ins.
val index : string -> char -> intβindex s cisString.index_from s 0 c. That's the whole vibe check.val index_opt : string -> char -> int optionβindex_opt s cisString.index_from_opt s 0 c.
β¨ Since 4.05
val rindex : string -> char -> intβrindex s cisString.rindex_from s (length s - 1) c. Starting from the end, main character energy πval rindex_opt : string -> char -> int optionβrindex_opt s cisString.rindex_from_opt s (length s - 1) c.
β¨ Since 4.05
π§΅ Finding substrings
Note. To find the same sub string multiple times, partially applying the ~sub argument of these functions and using the resulting function repeatedly is more efficient. Little performance glow-up, no cap π
val find_first : sub:string -> ?start:int -> string -> int optionβfind_first sub start sis the starting position of the first occurrence ofsubinsat or after the index or positionstart(defaults to0).
If sub is "" the result is Some start. The result of the function is always a valid index of s except when sub is "" and start is length s. Read that twice, it's lowkey doing a lot π«Ά
β¨ Since 5.5
- Raises
Invalid_argumentifstartis not a valid position ofs.
val find_last : sub:string -> ?start:int -> string -> int optionβfind_last sub start sis the starting position of the last occurrence ofsubinsat or before the index or positionstart(defaults toString.length s).
If sub is "" the result is Some start. The result of the function is always a valid index of s except when sub is "" and start is length s.
β¨ Since 5.5
- Raises
Invalid_argumentifstartis not a valid position ofs.
val find_all : sub:string -> (int -> 'acc -> 'acc) -> ?start:int -> string -> 'acc -> 'accβfind_all sub f start s acc, starting withacc, foldsfby increasing index order over all non-overlapping starting positions ofsubinsat or after the index or positionstart(defaults to0). The result isaccifsubcould not be found ins.
If sub is "", f gets invoked on all positions of s at or after start.
β¨ Since 5.5
- Raises
Invalid_argumentifstartis not a valid position ofs.
val rfind_all : sub:string -> (int -> 'acc -> 'acc) -> ?start:int -> string -> 'acc -> 'accβrfind_all sub f start s acc, starting withacc, foldsfby decreasing index order over all non-overlapping starting positions ofsubinsat or before the index or positionstart(defaults toString.length s). The result isaccifsubcould not be found ins.
If sub is "", f gets invoked on all positions of s at or before start.
β¨ Since 5.5
- Raises
Invalid_argumentifstartis not a valid position ofs.
π Replacing substrings
Note. To replace the same sub string multiple times, partially applying the ~sub argument of these functions and using the resulting function repeatedly is more efficient.
val replace_first : sub:string -> by:string -> ?start:int -> string -> stringβreplace_first sub by start sreplaces by by the first occurrence ofsubinsat or after the index or positionstart(defaults to0).
If sub is "", this inserts by at position start. Sneaky little insert, love her π
β¨ Since 5.5
- Raises
Invalid_argumentifstartis not a valid position ofs.
val replace_last : sub:string -> by:string -> ?start:int -> string -> stringβreplace_last sub by start sreplaces by by the last occurrence ofsubinsat or after the index or positionstart(defaults toString.length s).
If sub is "", this inserts by at position start.
β¨ Since 5.5
- Raises
Invalid_argumentifstartis not a valid position ofs.
val replace_all : sub:string -> by:string -> ?start:int -> string -> stringβreplace_all sub by start sreplaces by by all non-overlapping occurrences ofsubinsat or after the index or positionstart(defaults to0). Occurrences are found in increasing indexing order.
If sub is "", this inserts by on all positions from start on.
β¨ Since 5.5
- Raises
Invalid_argumentifstartis not a valid position ofs.
π¦ Strings and Sequences
val to_seq : t -> char Seq.tβto_seq sis a sequence made of the string's characters in increasing order.
β¨ Since 4.07
val to_seqi : t -> (int * char) Seq.tβto_seqi sis likeString.to_seqbut also tuples the corresponding index. Extra info, zero extra effort π
β¨ Since 4.07
val of_seq : char Seq.t -> tβof_seq sis a string made of the sequence's characters.
β¨ Since 4.07
π UTF decoding and validations
UTF-8
val get_utf_8_uchar : t -> int -> Uchar.utf_decodeβget_utf_8_uchar b idecodes an UTF-8 character at indexiinb.val is_valid_utf_8 : t -> boolβis_valid_utf_8 bistrueif and only ifbcontains valid UTF-8 data.
UTF-16BE
val get_utf_16be_uchar : t -> int -> Uchar.utf_decodeβget_utf_16be_uchar b idecodes an UTF-16BE character at indexiinb.val is_valid_utf_16be : t -> boolβis_valid_utf_16be bistrueif and only ifbcontains valid UTF-16BE data.
UTF-16LE
val get_utf_16le_uchar : t -> int -> Uchar.utf_decodeβget_utf_16le_uchar b idecodes an UTF-16LE character at indexiinb.val is_valid_utf_16le : t -> boolβis_valid_utf_16le bistrueif and only ifbcontains valid UTF-16LE data.
π Spellchecking
val edit_distance : ?limit:int -> t -> t -> intβedit_distance s0 s1is the number of single character edits (understood as insertion, deletion, substitution, transposition) that are needed to changes0intos1.
If limit is provided the function returns with limit as soon as it was determined that s0 and s1 have distance of at least limit. This is faster if you have a fixed limit, for example for spellchecking. Speed queen behavior β‘
The function assumes the strings are UTF-8 encoded and uses Uchar.t for the notion of character. Decoding errors are replaced by Uchar.rep. Normalizing the strings to NFC gives better results.
Note. This implements the simpler Optimal String Alignment (OSA) distance, not the Damerau-Levenshtein distance. With this function"ca"and"abc"have a distance of 3 not 2. Do not come for her about that, it's literally documented π
β¨ Since 5.4
val spellcheck : ?max_dist:(string -> int) -> ((string -> unit) -> unit) -> string -> string listβspellcheck iter_dict sare the strings enumerated by the iteratoriter_dictwhoseString.edit_distancetosis the smallest and at mostmax_dist s. If multiple corrections are returned their order is as found initer_dict. The defaultmax_dist sis:0ifshas 0 to 2 Unicode characters.1ifshas 3 to 4 Unicode characters.2otherwise.
If your dictionary is a list l, a suitable iter_dict is given by (fun yield -> List.iter yield l).
All strings are assumed to be UTF-8 encoded, decoding errors are replaced by Uchar.rep characters.
β¨ Since 5.4
π’ Binary decoding of integers
The functions in this section binary decode integers from strings. Yes, we're going from vibes to raw bytes, buckle up π
All following functions raise Invalid_argument if the characters needed at index i to decode the integer are not available.
Little-endian (resp. big-endian) encoding means that least (resp. most) significant bytes are stored first. Big-endian is also known as network byte order β yes bestie, that's the same thing you see in all your networking code, it's not a different vibe π
. Native-endian encoding is either little-endian or big-endian depending on Sys.big_endian, so it's like, whatever your machine woke up feeling today.
The int types, explained
32-bit and 64-bit integers are represented by the int32 and int64 types, which can be interpreted either as signed or unsigned numbers. Choose your fighter β¨
8-bit and 16-bit integers are represented by the int type, which has more bits than the binary encoding. These extra bits are sign-extended (or zero-extended) for functions which decode 8-bit or 16-bit integers and represented them with int values. So like, the int is wearing a little extra padding, it's giving oversized hoodie energy π«Ά
πΈ The getters, one by one πΈ
val get_uint8 : string -> int -> intβget_uint8 b iisb's unsigned 8-bit integer starting at character indexi. Since 4.13val get_int8 : string -> int -> intβget_int8 b iisb's signed 8-bit integer starting at character indexi. Since 4.13val get_uint16_ne : string -> int -> intβget_uint16_ne b iisb's native-endian unsigned 16-bit integer starting at character indexi. Since 4.13val get_uint16_be : string -> int -> intβget_uint16_be b iisb's big-endian unsigned 16-bit integer starting at character indexi. Since 4.13val get_uint16_le : string -> int -> intβget_uint16_le b iisb's little-endian unsigned 16-bit integer starting at character indexi. Since 4.13val get_int16_ne : string -> int -> intβget_int16_ne b iisb's native-endian signed 16-bit integer starting at character indexi. Since 4.13val get_int16_be : string -> int -> intβget_int16_be b iisb's big-endian signed 16-bit integer starting at character indexi. Since 4.13val get_int16_le : string -> int -> intβget_int16_le b iisb's little-endian signed 16-bit integer starting at character indexi. Since 4.13val get_int32_ne : string -> int -> int32βget_int32_ne b iisb's native-endian 32-bit integer starting at character indexi. Since 4.13val hash : t -> intβ an unseeded hash function for strings, with the same output value asHashtbl.hash. This function allows this module to be passed as argument to the functorHashtbl.Make. Since 5.0val seeded_hash : int -> t -> intβ a seeded hash function for strings, with the same output value asHashtbl.seeded_hash. This function allows this module to be passed as argument to the functorHashtbl.MakeSeeded. Since 5.0val get_int32_be : string -> int -> int32βget_int32_be b iisb's big-endian 32-bit integer starting at character indexi. Since 4.13val get_int32_le : string -> int -> int32βget_int32_le b iisb's little-endian 32-bit integer starting at character indexi. Since 4.13val get_int64_ne : string -> int -> int64βget_int64_ne b iisb's native-endian 64-bit integer starting at character indexi. Since 4.13val get_int64_be : string -> int -> int64βget_int64_be b iisb's big-endian 64-bit integer starting at character indexi. Since 4.13val get_int64_le : string -> int -> int64βget_int64_le b iisb's little-endian 64-bit integer starting at character indexi. Since 4.13
Quick vibe check, bestie: notice there's noget_uint32orget_uint64in this list β the 32-bit and 64-bit getters are the plainint32/int64ones up there, and the signed/unsigned call is on you. Don't go inventing functions that aren't on this page π
And that's the whole module, no cap β you read every single getter, both hash functions, and the endianness lore. Go decode something iconic β¨π
This page came from the OCamldoc source, version-and-dated 2026-06-22, and it's the String(3) manual page π slay, go touch some grass now, you've earned it πΈπ¦
π¦ where this page comes from
- arch rolling: ocaml 5.5.0-1 Β· LGPL2.1 AND custom: QPL-1.0
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms