# `String`
[ð](https://github.com/elixir-lang/elixir/blob/v1.20.1/lib/elixir/lib/string.ex#L7)
Strings in Elixir are UTF-8 encoded binaries.
Strings in Elixir are a sequence of Unicode characters,
typically written between double quoted strings, such
as `"hello"` and `"héllò"`.
In case a string must have a double-quote in itself,
the double quotes must be escaped with a backslash,
for example: `"this is a string with \"double quotes\""`.
You can concatenate two strings with the `<>/2` operator:
iex> "hello" <> " " <> "world"
"hello world"
The functions in this module act according to
[The Unicode Standard, Version 17.0.0](https://www.unicode.org/versions/Unicode17.0.0/).
## Interpolation
Strings in Elixir also support interpolation. This allows
you to place some value in the middle of a string by using
the `#{}` syntax:
iex> name = "joe"
iex> "hello #{name}"
"hello joe"
Any Elixir expression is valid inside the interpolation.
If a string is given, the string is interpolated as is.
If any other value is given, Elixir will attempt to convert
it to a string using the `String.Chars` protocol. This
allows, for example, to output an integer from the interpolation:
iex> "2 + 2 = #{2 + 2}"
"2 + 2 = 4"
In case the value you want to interpolate cannot be
converted to a string, because it doesn't have a human
textual representation, a protocol error will be raised.
## Escape characters
Besides allowing double-quotes to be escaped with a backslash,
strings also support the following escape characters:
* `\0` - Null byte
* `\a` - Bell
* `\b` - Backspace
* `\t` - Horizontal tab
* `\n` - Line feed (New lines)
* `\v` - Vertical tab
* `\f` - Form feed
* `\r` - Carriage return
* `\e` - Command Escape
* `\s` - Space
* `\#` - Returns the `#` character itself, skipping interpolation
* `\\` - Single backslash
* `\xNN` - A byte represented by the hexadecimal `NN`
* `\uNNNN` - A Unicode code point represented by `NNNN`
* `\u{NNNNNN}` - A Unicode code point represented by `NNNNNN`
Note it is generally not advised to use `\xNN` in Elixir
strings, as introducing an invalid byte sequence would
make the string invalid. If you have to introduce a
character by its hexadecimal representation, it is best
to work with Unicode code points, such as `\uNNNN`. In fact,
understanding Unicode code points can be essential when doing
low-level manipulations of string, so let's explore them in
detail next.
## Unicode and code points
In order to facilitate meaningful communication between computers
across multiple languages, a standard is required so that the ones
and zeros on one machine mean the same thing when they are transmitted
to another. The Unicode Standard acts as an official registry of
virtually all the characters we know: this includes characters from
classical and historical texts, emoji, and formatting and control
characters as well.
Unicode organizes all of the characters in its repertoire into code
charts, and each character is given a unique numerical index. This
numerical index is known as a Code Point.
In Elixir you can use a `?` in front of a character literal to reveal
its code point:
iex> ?a
97
iex> ?Å
322
Note that most Unicode code charts will refer to a code point by its
hexadecimal (hex) representation, e.g. `97` translates to `0061` in hex,
and we can represent any Unicode character in an Elixir string by
using the `\u` escape character followed by its code point number:
iex> "\u0061" === "a"
true
iex> 0x0061 = 97 = ?a
97
The hex representation will also help you look up information about a
code point, e.g. [https://codepoints.net/U+0061](https://codepoints.net/U+0061)
has a data sheet all about the lower case `a`, a.k.a. code point 97.
Remember you can get the hex presentation of a number by calling
`Integer.to_string/2`:
iex> Integer.to_string(?a, 16)
"61"
## UTF-8 encoded and encodings
Now that we understand what the Unicode standard is and what code points
are, we can finally talk about encodings. Whereas the code point is **what**
we store, an encoding deals with **how** we store it: encoding is an
implementation. In other words, we need a mechanism to convert the code
point numbers into bytes so they can be stored in memory, written to disk, and such.
Elixir uses UTF-8 to encode its strings, which means that code points are
encoded as a series of 8-bit bytes. UTF-8 is a **variable width** character
encoding that uses one to four bytes to store each code point. It is capable
of encoding all valid Unicode code points. Let's see an example:
iex> string = "héllo"
"héllo"
iex> String.length(string)
5
iex> byte_size(string)
6
Although the string above has 5 characters, it uses 6 bytes, as two bytes
are used to represent the character `é`.
## Grapheme clusters
This module also works with the concept of grapheme cluster
(from now on referenced as graphemes). Graphemes can consist
of multiple code points that may be perceived as a single character
by readers. For example, "é" can be represented either as a single
"e with acute" code point, as seen above in the string `"héllo"`,
or as the letter "e" followed by a "combining acute accent"
(two code points):
iex> string = "\u0065\u0301"
"eÌ"
iex> byte_size(string)
3
iex> String.length(string)
1
iex> String.codepoints(string)
["e", "Ì"]
iex> String.graphemes(string)
["eÌ"]
Although it looks visually the same as before, the example above
is made of two characters, it is perceived by users as one.
Graphemes can also be two characters that are interpreted as one
by some languages. For example, some languages may consider "ch"
as a single character. However, since this information depends on
the locale, it is not taken into account by this module.
In general, the functions in this module rely on the Unicode
Standard, but do not contain any of the locale specific behavior.
More information about graphemes can be found in the [Unicode
Standard Annex #29](https://www.unicode.org/reports/tr29/).
For converting a binary to a different encoding and for Unicode
normalization mechanisms, see Erlang's [`:unicode`](`:unicode`) module.
## String and binary operations
To act according to the Unicode Standard, many functions
in this module run in linear time, as they need to traverse
the whole string considering the proper Unicode code points.
For example, `String.length/1` will take longer as
the input grows. On the other hand, `Kernel.byte_size/1` always runs
in constant time (i.e. regardless of the input size).
This means often there are performance costs in using the
functions in this module, compared to the more low-level
operations that work directly with binaries:
* `Kernel.binary_part/3` - retrieves part of the binary
* `Kernel.bit_size/1` and `Kernel.byte_size/1` - size related functions
* `Kernel.is_bitstring/1` and `Kernel.is_binary/1` - type-check function
* Plus a number of functions for working with binaries (bytes)
in the [`:binary` module](`:binary`)
A `utf8` modifier is also available inside the binary syntax `<<>>`.
It can be used to match code points out of a binary/string:
iex> <<:utf8>> = "é"
iex> eacute
233
See the [*Patterns and Guards* guide](patterns-and-guards.md) and the documentation for
[`<<>>`](`<<>>/1`) for more information on binary pattern matching.
You can also fully convert a string into a list of integer code points,
known as "charlists" in Elixir, by calling `String.to_charlist/1`:
iex> String.to_charlist("héllo")
[104, 233, 108, 108, 111]
If you would rather see the underlying bytes of a string, instead of
its codepoints, a common trick is to concatenate the null byte `<<0>>`
to it:
iex> "héllo" <> <<0>>
<<104, 195, 169, 108, 108, 111, 0>>
Alternatively, you can view a string's binary representation by
passing an option to `IO.inspect/2`:
IO.inspect("héllo", binaries: :as_binaries)
#=> <<104, 195, 169, 108, 108, 111>>
## Self-synchronization
The UTF-8 encoding is self-synchronizing. This means that
if malformed data (i.e., data that is not possible according
to the definition of the encoding) is encountered, only one
code point needs to be rejected.
This module relies on this behavior to ignore such invalid
characters. For example, `length/1` will return
a correct result even if an invalid code point is fed into it.
In other words, this module expects invalid data to be detected
elsewhere, usually when retrieving data from the external source.
For example, a driver that reads strings from a database will be
responsible to check the validity of the encoding. `String.chunk/2`
can be used for breaking a string into valid and invalid parts.
## Compile binary patterns
Many functions in this module work with patterns. For example,
`String.split/3` can split a string into multiple strings given
a pattern. This pattern can be a string, a list of strings or
a compiled pattern:
iex> String.split("foo bar", " ")
["foo", "bar"]
iex> String.split("foo bar!", [" ", "!"])
["foo", "bar", ""]
iex> pattern = :binary.compile_pattern([" ", "!"])
iex> String.split("foo bar!", pattern)
["foo", "bar", ""]
The compiled pattern is useful when the same match will
be done over and over again. Note though that the compiled
pattern cannot be stored in a module attribute as the pattern
is generated at runtime and does not survive compile time.
# `codepoint`
```elixir
@type codepoint() :: t()
```
A single Unicode code point encoded in UTF-8. It may be one or more bytes.
# `grapheme`
```elixir
@type grapheme() :: t()
```
Multiple code points that may be perceived as a single character by readers
# `pattern`
```elixir
@type pattern() ::
t() | [nonempty_binary()] | (compiled_search_pattern :: :binary.cp())
```
Pattern used in functions like `replace/4` and `split/3`.
It must be one of:
* a string
* an empty list
* a list containing non-empty strings
* a compiled search pattern created by `:binary.compile_pattern/1`
# `replace_opts`
```elixir
@type replace_opts() :: [{:global, boolean()}]
```
# `split_opts`
```elixir
@type split_opts() :: [parts: pos_integer() | :infinity, trim: boolean()]
```
# `splitter_opts`
```elixir
@type splitter_opts() :: [{:trim, boolean()}]
```
# `t`
```elixir
@type t() :: binary()
```
A UTF-8 encoded binary.
The types `String.t()` and `binary()` are equivalent to analysis tools.
Although, for those reading the documentation, `String.t()` implies
it is a UTF-8 encoded binary.
# `at`
```elixir
@spec at(t(), integer()) :: grapheme() | nil
```
Returns the grapheme at the `position` of the given UTF-8 `string`.
If `position` is greater than `string` length, then it returns `nil`.
> #### Linear Access {: .warning}
>
> This function has to linearly traverse the string.
> If you want to access a string or a binary in constant time based on the
> number of bytes, use `Kernel.binary_slice/3` or `:binary.at/2` instead.
## Examples
iex> String.at("elixir", 0)
"e"
iex> String.at("elixir", 1)
"l"
iex> String.at("elixir", 10)
nil
iex> String.at("elixir", -1)
"r"
iex> String.at("elixir", -10)
nil
# `bag_distance`
*since 1.8.0*
```elixir
@spec bag_distance(t(), t()) :: float()
```
Computes the bag distance between two strings.
Returns a float value between 0 and 1 representing the bag
distance between `string1` and `string2`.
The bag distance is meant to be an efficient approximation
of the distance between two strings to quickly rule out strings
that are largely different.
The algorithm is outlined in the "String Matching with Metric
Trees Using an Approximate Distance" paper by Ilaria Bartolini,
Paolo Ciaccia, and Marco Patella.
## Examples
iex> String.bag_distance("abc", "")
0.0
iex> String.bag_distance("abcd", "a")
0.25
iex> String.bag_distance("abcd", "ab")
0.5
iex> String.bag_distance("abcd", "abc")
0.75
iex> String.bag_distance("abcd", "abcd")
1.0
# `byte_slice`
*since 1.17.0*
```elixir
@spec byte_slice(t(), integer(), non_neg_integer()) :: t()
```
Returns a substring starting at (or after) `start_bytes` and of at most
the given `size_bytes`.
This function works on bytes and then adjusts the string to eliminate
truncated codepoints. This is useful when you have a string and you need
to guarantee it does not exceed a certain amount of bytes.
If the offset is greater than the number of bytes in the string, then it
returns `""`. Similar to `String.slice/2`, a negative `start_bytes`
will be adjusted to the end of the string (but in bytes).
This function does not guarantee the string won't have invalid codepoints,
it only guarantees to remove truncated codepoints immediately at the beginning
or the end of the slice.
## Examples
Consider the string "héllo". Let's see its representation:
iex> inspect("héllo", binaries: :as_binaries)
"<<104, 195, 169, 108, 108, 111>>"
Although the string has 5 characters, it is made of 6 bytes. Now imagine
we want to get only the first two bytes. To do so, let's use `binary_slice/3`,
which is unaware of codepoints:
iex> binary_slice("héllo", 0, 2)
<<104, 195>>
As you can see, this operation is unsafe and returns an invalid string.
That's because we cut the string in the middle of the bytes representing
"é". On the other hand, we could use `String.slice/3`:
iex> String.slice("héllo", 0, 2)
"hé"
While the above is correct, it has 3 bytes. If you have a requirement where
you need *at most* 2 bytes, the result would also be invalid. In such scenarios,
you can use this function, which will slice the given bytes, but clean up
the truncated codepoints:
iex> String.byte_slice("héllo", 0, 2)
"h"
Truncated codepoints at the beginning are also cleaned up:
iex> String.byte_slice("héllo", 2, 3)
"llo"
Note that, if you want to work on raw bytes, then you must use `binary_slice/3`
instead.
# `capitalize`
```elixir
@spec capitalize(t(), :default | :ascii | :greek | :turkic) :: t()
```
Converts the first character in the given string to
uppercase and the remainder to lowercase according to `mode`.
`mode` may be `:default`, `:ascii`, `:greek` or `:turkic`. The `:default` mode
considers all non-conditional transformations outlined in the Unicode standard.
`:ascii` capitalizes only the letters A to Z. `:greek` includes the context
sensitive mappings found in Greek. `:turkic` properly handles the letter `i`
with the dotless variant.
Also see `upcase/2` and `capitalize/2` for other conversions. If you want
a variation of this function that does not lowercase the rest of string,
see Erlang's `:string.titlecase/1`.
## Examples
iex> String.capitalize("abcd")
"Abcd"
iex> String.capitalize("ABCD")
"Abcd"
iex> String.capitalize("ï¬n")
"Fin"
iex> String.capitalize("olá")
"Olá"
# `chunk`
```elixir
@spec chunk(t(), :valid | :printable) :: [t()]
```
Splits the string into chunks of characters that share a common trait.
The trait can be one of two options:
* `:valid` - the string is split into chunks of valid and invalid
character sequences
* `:printable` - the string is split into chunks of printable and
non-printable character sequences
Returns a list of binaries each of which contains only one kind of
characters.
If the given string is empty, an empty list is returned.
## Examples
iex> String.chunk(<>, :valid)
[<<97, 98, 99, 0>>]
iex> String.chunk(<>, :valid)
[<<97, 98, 99, 0>>, <<255, 255>>]
iex> String.chunk(<>, :printable)
["abc", <<0, 239, 191, 191>>]
# `codepoints`
```elixir
@spec codepoints(t()) :: [codepoint()]
```
Returns a list of code points encoded as strings.
To retrieve code points in their natural integer
representation, see `to_charlist/1`. For details about
code points and graphemes, see the `String` module
documentation.
## Examples
iex> String.codepoints("olá")
["o", "l", "á"]
iex> String.codepoints("опÑÐ¸Ð¼Ñ Ð·Ð°ÑÑÑ")
["о", "п", "Ñ", "и", "м", "Ñ", " ", "з", "а", "Ñ", "Ñ", "Ñ"]
iex> String.codepoints("á¼
Ἢῼ")
["á¼
", "Ἢ", "ῼ"]
iex> String.codepoints("\u00e9")
["é"]
iex> String.codepoints("\u0065\u0301")
["e", "Ì"]
# `contains?`
```elixir
@spec contains?(t(), [t()] | pattern()) :: boolean()
```
Searches if `string` contains any of the given `contents`.
`contents` can be either a string, a list of strings,
or a compiled pattern. If `contents` is a list, this
function will search if any of the strings in `contents`
are part of `string`.
> #### Searching for a string in a list {: .tip}
>
> If you want to check if `string` is listed in `contents`,
> where `contents` is a list, use `Enum.member?(contents, string)`
> instead.
## Examples
iex> String.contains?("elixir of life", "of")
true
iex> String.contains?("elixir of life", ["life", "death"])
true
iex> String.contains?("elixir of life", ["death", "mercury"])
false
The argument can also be a compiled pattern:
iex> pattern = :binary.compile_pattern(["life", "death"])
iex> String.contains?("elixir of life", pattern)
true
An empty string will always match:
iex> String.contains?("elixir of life", "")
true
iex> String.contains?("elixir of life", ["", "other"])
true
An empty list will never match:
iex> String.contains?("elixir of life", [])
false
iex> String.contains?("", [])
false
Be aware that this function can match within or across grapheme boundaries.
For example, take the grapheme "é" which is made of the characters
"e" and the acute accent. The following returns `true`:
iex> String.contains?(String.normalize("é", :nfd), "e")
true
However, if "é" is represented by the single character "e with acute"
accent, then it will return `false`:
iex> String.contains?(String.normalize("é", :nfc), "e")
false
# `count`
*since 1.19.0*
```elixir
@spec count(t(), pattern() | Regex.t()) :: non_neg_integer()
```
Counts the number of non-overlapping occurrences of a `pattern` in a `string`.
In case the pattern is an empty string, the function returns 1 + the number of graphemes
in the string.
## Examples
iex> String.count("hello world", "o")
2
iex> String.count("hello world", "l")
3
iex> String.count("hello world", "x")
0
iex> String.count("hello world", ~r/o/)
2
iex> String.count("Hellooo", "oo")
1
iex> String.count("hello world", "")
12
The `pattern` can also be a list:
iex> String.count("hello world", ["e", "o"])
3
iex> String.count("hello world", [])
0
Or a compiled pattern:
iex> pattern = :binary.compile_pattern([" ", "!"])
iex> String.count("foo bar baz!!", pattern)
4
# `downcase`
```elixir
@spec downcase(t(), :default | :ascii | :greek | :turkic) :: t()
```
Converts all characters in the given string to lowercase according to `mode`.
`mode` may be `:default`, `:ascii`, `:greek` or `:turkic`. The `:default` mode considers
all non-conditional transformations outlined in the Unicode standard. `:ascii`
lowercases only the letters A to Z. `:greek` includes the context sensitive
mappings found in Greek. `:turkic` properly handles the letter i with the dotless variant.
Also see `upcase/2` and `capitalize/2` for other conversions.
## Examples
iex> String.downcase("ABCD")
"abcd"
iex> String.downcase("AB 123 XPTO")
"ab 123 xpto"
iex> String.downcase("OLÃ")
"olá"
The `:ascii` mode ignores Unicode characters and provides a more
performant implementation when you know the string contains only
ASCII characters:
iex> String.downcase("OLÃ", :ascii)
"olÃ"
The `:greek` mode properly handles the context sensitive sigma in Greek:
iex> String.downcase("ΣΣ")
"ÏÏ"
iex> String.downcase("ΣΣ", :greek)
"ÏÏ"
And `:turkic` properly handles the letter i with the dotless variant:
iex> String.downcase("Iİ")
"iiÌ"
iex> String.downcase("Iİ", :turkic)
"ıi"
# `duplicate`
```elixir
@spec duplicate(t(), non_neg_integer()) :: t()
```
Returns a string `subject` repeated `n` times.
Inlined by the compiler.
## Examples
iex> String.duplicate("abc", 0)
""
iex> String.duplicate("abc", 1)
"abc"
iex> String.duplicate("abc", 2)
"abcabc"
# `ends_with?`
```elixir
@spec ends_with?(t(), t() | [t()]) :: boolean()
```
Returns `true` if `string` ends with any of the suffixes given.
`suffixes` can be either a single suffix or a list of suffixes.
## Examples
iex> String.ends_with?("language", "age")
true
iex> String.ends_with?("language", ["youth", "age"])
true
iex> String.ends_with?("language", ["youth", "elixir"])
false
An empty suffix will always match:
iex> String.ends_with?("language", "")
true
iex> String.ends_with?("language", ["", "other"])
true
# `equivalent?`
```elixir
@spec equivalent?(t(), t()) :: boolean()
```
Returns `true` if `string1` is canonically equivalent to `string2`.
It performs Normalization Form Canonical Decomposition (NFD) on the
strings before comparing them. This function is equivalent to:
String.normalize(string1, :nfd) == String.normalize(string2, :nfd)
If you plan to compare multiple strings, multiple times in a row, you
may normalize them upfront and compare them directly to avoid multiple
normalization passes.
## Examples
iex> String.equivalent?("abc", "abc")
true
iex> String.equivalent?("man\u0303ana", "mañana")
true
iex> String.equivalent?("abc", "ABC")
false
iex> String.equivalent?("nø", "nó")
false
# `first`
```elixir
@spec first(t()) :: grapheme() | nil
```
Returns the first grapheme from a UTF-8 string,
`nil` if the string is empty.
## Examples
iex> String.first("elixir")
"e"
iex> String.first("Õ¥Õ¸Õ£Õ¬Õ«")
"Õ¥"
iex> String.first("")
nil
# `graphemes`
```elixir
@spec graphemes(t()) :: [grapheme()]
```
Returns Unicode graphemes in the string as per Extended Grapheme
Cluster algorithm.
The algorithm is outlined in the [Unicode Standard Annex #29,
Unicode Text Segmentation](https://www.unicode.org/reports/tr29/).
For details about code points and graphemes, see the `String` module documentation.
## Examples
iex> String.graphemes("Åaïve")
["Å", "a", "ï", "v", "e"]
iex> String.graphemes("\u00e9")
["é"]
iex> String.graphemes("\u0065\u0301")
["eÌ"]
# `jaro_distance`
```elixir
@spec jaro_distance(t(), t()) :: float()
```
Computes the Jaro distance (similarity) between two strings.
Returns a float value between `0.0` (equates to no similarity) and `1.0`
(is an exact match) representing [Jaro](https://en.wikipedia.org/wiki/Jaro-Winkler_distance)
distance between `string1` and `string2`.
The Jaro distance metric is designed and best suited for short
strings such as person names. Elixir itself uses this function
to provide the "did you mean?" functionality. For instance, when you
are calling a function in a module and you have a typo in the
function name, we attempt to suggest the most similar function
name available, if any, based on the `jaro_distance/2` score.
## Examples
iex> String.jaro_distance("Dwayne", "Duane")
0.8222222222222223
iex> String.jaro_distance("even", "odd")
0.0
iex> String.jaro_distance("same", "same")
1.0
# `last`
```elixir
@spec last(t()) :: grapheme() | nil
```
Returns the last grapheme from a UTF-8 string,
`nil` if the string is empty.
It traverses the whole string to find its last grapheme.
## Examples
iex> String.last("")
nil
iex> String.last("elixir")
"r"
iex> String.last("Õ¥Õ¸Õ£Õ¬Õ«")
"Õ«"
# `length`
```elixir
@spec length(t()) :: non_neg_integer()
```
Returns the number of Unicode graphemes in a UTF-8 string.
## Examples
iex> String.length("elixir")
6
iex> String.length("Õ¥Õ¸Õ£Õ¬Õ«")
5
# `match?`
```elixir
@spec match?(t(), Regex.t()) :: boolean()
```
Checks if `string` matches the given regular expression.
## Examples
iex> String.match?("foo", ~r/foo/)
true
iex> String.match?("bar", ~r/foo/)
false
Elixir also provides text-based match operator `=~/2` and function `Regex.match?/2` as
alternatives to test strings against regular expressions.
# `myers_difference`
*since 1.3.0*
```elixir
@spec myers_difference(t(), t()) :: [{:eq | :ins | :del, t()}]
```
Returns a keyword list that represents an edit script.
Check `List.myers_difference/2` for more information.
## Examples
iex> string1 = "fox hops over the dog"
iex> string2 = "fox jumps over the lazy cat"
iex> String.myers_difference(string1, string2)
[eq: "fox ", del: "ho", ins: "jum", eq: "ps over the ", del: "dog", ins: "lazy cat"]
# `next_codepoint`
```elixir
@spec next_codepoint(t()) :: {codepoint(), t()} | nil
```
Returns the next code point in a string.
The result is a tuple with the code point and the
remainder of the string or `nil` in case
the string reached its end.
As with other functions in the `String` module, `next_codepoint/1`
works with binaries that are invalid UTF-8. If the string starts
with a sequence of bytes that is not valid in UTF-8 encoding, the
first element of the returned tuple is a binary with the first byte.
## Examples
iex> String.next_codepoint("olá")
{"o", "lá"}
iex> invalid = "\x80\x80OK" # first two bytes are invalid in UTF-8
iex> {_, rest} = String.next_codepoint(invalid)
{<<128>>, <<128, 79, 75>>}
iex> String.next_codepoint(rest)
{<<128>>, "OK"}
## Comparison with binary pattern matching
Binary pattern matching provides a similar way to decompose
a string:
iex> <<:utf8 rest::binary>> = "Elixir"
"Elixir"
iex> codepoint
69
iex> rest
"lixir"
though not entirely equivalent because `codepoint` comes as
an integer, and the pattern won't match invalid UTF-8.
Binary pattern matching, however, is simpler and more efficient,
so pick the option that better suits your use case.
# `next_grapheme`
```elixir
@spec next_grapheme(t()) :: {grapheme(), t()} | nil
```
Returns the next grapheme in a string.
The result is a tuple with the grapheme and the
remainder of the string or `nil` in case
the String reached its end.
## Examples
iex> String.next_grapheme("olá")
{"o", "lá"}
iex> String.next_grapheme("")
nil
# `next_grapheme_size`
```elixir
@spec next_grapheme_size(t()) :: {pos_integer(), t()} | nil
```
Returns the size (in bytes) of the next grapheme.
The result is a tuple with the next grapheme size in bytes and
the remainder of the string or `nil` in case the string
reached its end.
## Examples
iex> String.next_grapheme_size("olá")
{1, "lá"}
iex> String.next_grapheme_size("")
nil
# `normalize`
```elixir
@spec normalize(t(), :nfd | :nfc | :nfkd | :nfkc) :: t()
```
Converts all characters in `string` to Unicode normalization
form identified by `form`.
Invalid Unicode codepoints are skipped and the remaining of
the string is converted. If you want the algorithm to stop
and return on invalid codepoint, use `:unicode.characters_to_nfd_binary/1`,
`:unicode.characters_to_nfc_binary/1`, `:unicode.characters_to_nfkd_binary/1`,
and `:unicode.characters_to_nfkc_binary/1` instead.
Normalization forms `:nfkc` and `:nfkd` should not be blindly applied
to arbitrary text. Because they erase many formatting distinctions,
they will prevent round-trip conversion to and from many legacy
character sets.
## Forms
The supported forms are:
* `:nfd` - Normalization Form Canonical Decomposition.
Characters are decomposed by canonical equivalence, and
multiple combining characters are arranged in a specific
order.
* `:nfc` - Normalization Form Canonical Composition.
Characters are decomposed and then recomposed by canonical equivalence.
* `:nfkd` - Normalization Form Compatibility Decomposition.
Characters are decomposed by compatibility equivalence, and
multiple combining characters are arranged in a specific
order.
* `:nfkc` - Normalization Form Compatibility Composition.
Characters are decomposed and then recomposed by compatibility equivalence.
## Examples
iex> String.normalize("yêsÌÌ£", :nfd)
"yeÌsÌ£Ì"
iex> String.normalize("lenÌa", :nfc)
"leña"
iex> String.normalize("ï¬", :nfkd)
"fi"
iex> String.normalize("fi", :nfkc)
"fi"
# `pad_leading`
```elixir
@spec pad_leading(t(), non_neg_integer(), t() | [t()]) :: t()
```
Returns a new string padded with a leading filler
which is made of elements from the `padding`.
Passing a list of strings as `padding` will take one element of the list
for every missing entry. If the list is shorter than the number of inserts,
the filling will start again from the beginning of the list.
Passing a string `padding` is equivalent to passing the list of graphemes in it.
If no `padding` is given, it defaults to whitespace.
When `count` is less than or equal to the length of `string`,
given `string` is returned.
Raises `ArgumentError` if the given `padding` contains a non-string element.
## Examples
iex> String.pad_leading("abc", 5)
" abc"
iex> String.pad_leading("abc", 4, "12")
"1abc"
iex> String.pad_leading("abc", 6, "12")
"121abc"
iex> String.pad_leading("abc", 5, ["1", "23"])
"123abc"
# `pad_trailing`
```elixir
@spec pad_trailing(t(), non_neg_integer(), t() | [t()]) :: t()
```
Returns a new string padded with a trailing filler
which is made of elements from the `padding`.
Passing a list of strings as `padding` will take one element of the list
for every missing entry. If the list is shorter than the number of inserts,
the filling will start again from the beginning of the list.
Passing a string `padding` is equivalent to passing the list of graphemes in it.
If no `padding` is given, it defaults to whitespace.
When `count` is less than or equal to the length of `string`,
given `string` is returned.
Raises `ArgumentError` if the given `padding` contains a non-string element.
## Examples
iex> String.pad_trailing("abc", 5)
"abc "
iex> String.pad_trailing("abc", 4, "12")
"abc1"
iex> String.pad_trailing("abc", 6, "12")
"abc121"
iex> String.pad_trailing("abc", 5, ["1", "23"])
"abc123"
# `printable?`
```elixir
@spec printable?(t(), 0) :: true
@spec printable?(t(), pos_integer() | :infinity) :: boolean()
```
Checks if a string contains only printable characters up to `character_limit`.
Takes an optional `character_limit` as a second argument. If `character_limit` is `0`, this
function will return `true`.
## Examples
iex> String.printable?("abc")
true
iex> String.printable?("abc" <> <<0>>)
false
iex> String.printable?("abc" <> <<0>>, 2)
true
iex> String.printable?("abc" <> <<0>>, 0)
true
# `replace`
```elixir
@spec replace(
t(),
pattern() | Regex.t(),
t() | (t() -> t() | iodata()),
replace_opts()
) :: t()
```
Returns a new string created by replacing occurrences of `pattern` in
`subject` with `replacement`.
The `subject` is always a string.
The `pattern` may be a string, a list of strings, a regular expression, or a
compiled pattern.
The `replacement` may be a string or a function that receives the matched
pattern and must return the replacement as a string or iodata.
By default it replaces all occurrences but this behavior can be controlled
through the `:global` option; see the "Options" section below.
## Options
* `:global` - (boolean) if `true`, all occurrences of `pattern` are replaced
with `replacement`, otherwise only the first occurrence is
replaced. Defaults to `true`
## Examples
iex> String.replace("a,b,c", ",", "-")
"a-b-c"
iex> String.replace("a,b,c", ",", "-", global: false)
"a-b,c"
The pattern may also be a list of strings and the replacement may also
be a function that receives the matches:
iex> String.replace("a,b,c", ["a", "c"], fn <